CSS允许您创建动态页面布局和Web项目界面。 但是CSS是一种静态语言。 设置特定值后,将无法更改。 此处不考虑随机更改某些值的想法。

随机数生成是CSS无法输入的JavaScript领域。 但是,如果这不是完全正确的呢? 实际上,如果考虑到用户执行的操作,这将为CSS添加一些随机性。 该材料的作者(我们今天将其翻译发表)提议对此进行讨论。
外部CSS随机化
您可以使用CSS变量在CSS中实现“动态随机化”之类的功能。
这是一些好东西。 但是,此类问题的解决方案不是纯CSS。 在这里,您需要使用JavaScript功能将新的随机值写入CSS变量。
您可以使用Sass或Less等预处理器来生成随机值。 但是在编译并导出CSS代码后,这些值是固定的,并且随机元素丢失了。 在有关此主题的一条
推文中 ,将这种设置CSS值的方法与小说主人公名字的随机选择进行了比较,该小说一旦写在纸上就不会改变。
为什么我对在CSS中使用随机值感兴趣?
我曾经开发过仅基于CSS的简单应用程序。 这是
测验 ,是
西蒙的游戏和
纸牌技巧 。 但是我想做些更复杂的事情。 在这里,我不讨论这种方法的正确性问题,仅基于CSS的项目的实用性或实际适用性问题。
基于某些棋盘游戏可以表示为有限状态机(FSM)的前提,我们可以得出结论,此类游戏只能使用HTML和CSS来实现。 带着这个想法,我开始开发游戏“
蛇和梯子 ”。 这是一个简单的游戏。 它的目标是扔一个骰子,从比赛场地的起点到最后一个骰子,同时避开蛇并尝试使用楼梯。
在我看来,这个项目可以用HTML和CSS完成。 但是,我没有考虑到某些东西。 关于骰子。
骰子卷(以及硬币卷)被普遍认为是随机值的“生成器”。 每次扔骨头或硬币,我们都会得到以前未知的东西。
掷骰子模仿
我打算将带有标签的图层叠加在一起,并使用CSS动画来“滚动”它们,从而更改顶层。 看起来类似于以下所示。
在浏览器中模拟图层动画实现这种用于获得随机值的系统的代码并不特别复杂。 它包括使用各种延迟的动画说明。 这是代码:
@keyframes changeOrder { from { z-index: 6; } to { z-index: 1; } } label { animation: changeOrder 3s infinite linear; background: #ddd; cursor: pointer; display: block; left: 1rem; padding: 1rem; position: absolute; top: 1rem; user-select: none; } 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; }
请注意,放慢了动画的速度,以便与相应的元素进行交互会更容易(但是事实证明它足够快,足以引起问题,下面将对此进行讨论)。 在这里,所呈现的机制的伪随机性质清晰可见。
→
这是 CodePen上的
一个项目,可让您探索这种方法
掷骰子模仿实际上,我在这里遇到了一个问题。 我的程序给出了随机值,但是有时候,即使我单击模拟骨骼投掷的按钮,系统也什么也没返回。
我试图增加动画时间,在我看来,这稍微改善了这种情况,但是系统仍然无法正常工作。
那时,我做了所有程序员所做的事情,面临着他们无法使用搜索引擎解决的问题。 我问了一个关于StackOverflow的
问题 。
为了我的幸福,他们向我解释了所有事情,并提出了
解决问题的
办法 。
我的问题的简化描述可以表示为:“仅当
mousedown
事件发生时处于活动状态的元素在
mouseup
事件发生时仍处于活动状态时,浏览器才会触发元素的
click
事件。”
由于这些元素不断地相互替换-
mousedown
鼠标按钮时发生
mousedown
事件的顶部元素并不总是与
mouseup
按钮时发生
mouseup
事件的元素相同。 为了在同一元素位于堆栈顶部时立即按下并释放按钮,必须足够快地执行单击(以便该元素没有时间离开堆栈顶部),或者必须缓慢地执行(因此该元素有机会回到顶部,绕一个完整的圆圈)。 这就是为什么增加动画时间可以掩盖问题的原因。
解决方案是使用
static
值作为活动元素的
position
属性,将其从元素堆栈中删除。 此外,分配了非常大的
z-index
值的伪元素(例如
::before
或
::after
代替了。 通过这种方法,释放鼠标按钮时,活动元素将始终位于堆栈的顶部。
label:active { margin-left: 200%; position: static; } label:active::before { content: ""; position: absolute; top: 0; right: 0; left: 0; bottom: 0; z-index: 10; }
这是一个实施此解决方案并使用更快动画的项目。
在对项目进行更改后,我只需要将自己的成就添加到游戏中即可。
那就是我得到的。
成品游戏该方法的缺点
此处描述的随机方法有明显的不便之处:
- 因其工作需要用户参与。 该人员必须单击标签才能启动“生成随机值”的过程。
- 它的伸缩性不好。 此方法非常适合处理少量值,但是如果需要从较大范围中获取随机值,则使用它非常不便。
- 它的应用程序允许获取的不是随机值,而是伪随机值。 关键是计算机可以很容易地发现某个时间点将发出什么“随机”值。
总结
尽管存在上述局限性,此处介绍的方法还是基于纯CSS。 要使用它,不需要预处理器或某些外部辅助机制。 对于用户来说,它的使用看起来就像程序产生完全随机数一样。
顺便说一下,该方法不仅适用于生成随机数。 它允许您随机化任何东西。 例如,在
该项目中,它基于计算机在“石头,剪刀,纸”游戏中做出的“随机”选择。
纯CSS游戏“石头,剪刀,纸”亲爱的读者们! 您是否打算在项目中使用本材料中突出显示的想法?
