前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【译】CSS中存在随机数吗?

【译】CSS中存在随机数吗?

作者头像
腾讯IVWEB团队
发布2020-06-28 10:39:41
1.7K0
发布2020-06-28 10:39:41
举报
文章被收录于专栏:腾讯IVWEB团队的专栏

CSS允许在网站上创建动态布局和接口,但作为一种语言,它是静态的:一旦设置了一个值,就不能更改。随机性的概念不在讨论范围之内。在运行时生成随机数是JavaScript的领域,而不是CSS的领域。真的是这样吗?如果我们考虑到一点用户交互因素,我们实际上可以在CSS中生成一定程度的随机性。让我们一起来看看!

其他语言的随机化

正如Robin Rendle在一篇关于CSS技巧的文章中解释的那样,可以使用CSS变量实现一些“动态随机化”。但是这些解决方案不是100%的CSS,因为它们需要用JavaScript产生随机数更新CSS变量。

我们可以使用Sass或Less的预处理器来生成随机值,但是一旦CSS代码被编译和导出,这些值就会被固定,并且失去了随机性。正如Jake Albaugh所说:

avatar

为什么我关心CSS中的随机数

在过去,我曾开发过一些简单的只使用CSS的应用程序,如益智游戏、Simon游戏和魔术。但是我想做一些更复杂的事情。稍后我将讨论有效性、实用性或创建这些只使用CSS的代码片段的实用性。

基于某些桌游可以表示为有限状态机(FSM),它们可以使用HTML和CSS表示。于是我开始开发一款蛇与梯子的游戏(又称瀑布与梯子)。这是一个简单的游戏。目标是通过避开蛇并试图爬上梯子,将棋子从棋盘的开始推进到最后。

这个项目似乎可行,但我错过了一样东西:掷骰子!

掷骰子(以及抛硬币)是公认的随机算法。掷骰子或抛硬币,每次都得到一个未知的值。

模拟随机掷骰子

我打算用标签叠加层,并使用CSS动画“旋转”和交换哪个层在上面。像这样:

avatar

模拟这种随机化的代码不是很复杂,可以通过动画和不同的动画延迟来实现:

代码语言:javascript
复制
/* The highest z-index is the numbers of sides in the dice */ 
@keyframes changeOrder {
  from { z-index: 6; } 
  to { z-index: 1; } 
} 

/* All the labels overlap by using absolute positioning */ 
label { 
  animation: changeOrder 3s infinite linear;
  background: #ddd;
  cursor: pointer;
  display: block;
  left: 1rem;
  padding: 1rem;
  position: absolute;
  top: 1rem; 
  user-select: none;
} 
/* Negative delay so all parts of the animation are in motion */ 
label:nth-of-type(1) { animation-delay: -0.0s; } 
label:nth-of-type(2) { animation-delay: -0.5s; } 
label:nth-of-type(3) { animation-delay: -1.0s; } 
label:nth-of-type(4) { animation-delay: -1.5s; } 
label:nth-of-type(5) { animation-delay: -2.0s; } 
label:nth-of-type(6) { animation-delay: -2.5s; }

注:动画已经被放慢,以使交互更容易(但仍然足够快,可以看到下面解释的问题)。伪随机性也更明显。

这里是个例子

但后来我遇到了一个问题:我得到的是随机数,但有时,即使我点击“骰子”,它也不会返回任何值。

我试着增加动画的时间,这似乎有点帮助,但仍然得到一些非预期值。

那时我做了一件大多数开发人员会做的事情:当他们发现他们不能在线搜索到问题的答案时,就用StackOverflow向其他开发人员寻求帮助,优秀的Temani Afif想出了一个解决方案

简单地说,问题是浏览器只在鼠标行为向下与向上的元素相同时才触发click/press事件。

由于旋转动画,鼠标向下的顶部标签不是鼠标向上的顶部标签,除非我时间设置得足够快或足够慢,让动画绕一圈。这增加动画时间隐藏了这些问题的原因。

解决方案是应用一个“static”定位来打破堆叠上下文,并使用一个伪元素,如::before或::after,以及一个更大的z-index来占位。这样,当鼠标向上移动时,active标签总是在顶部。

代码语言:javascript
复制
/* The active tag will be static and moved out of the window */ 
label:active {
  margin-left: 200%;
  position: static;
}

/* A pseudo-element of the label occupies all the space with a higher z-index */
label:active::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  z-index: 10;
}

这里的代码与解决方案有更快的动画时间。

在改掉这些之后,剩下的事就是创建一个小的界面来绘制一个可点击的假骰子,CSS版的《蛇和梯子》就完成了。

这种方法有一些明显的缺陷

  • 它需要用户输入:必须单击一个标签才能触发“随机数生成”。
  • 它的伸缩性不是很好:它在小范围数字集合上很有效,但是对于大范围的数字集合来说却很麻烦。
  • 它不是真正的随机,而是伪随机:计算机可以很容易地检测出在每个时刻会生成哪些值。

但另一方面,它是100%使用 CSS(不需要预处理程序或其他外部语言的帮助),对于用户来说,它看起来是100%随机的。

这种方法不仅适用于随机数,而且适用于任何随机情况。在这种情况下,我们用它可以使机器“随机”与我们进行“石头-剪刀-布”游戏

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 其他语言的随机化
  • 为什么我关心CSS中的随机数
  • 模拟随机掷骰子
  • 这种方法有一些明显的缺陷
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档