CSS中有随机数吗?

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动画来“滚动”它们,从而更改顶层。 看起来类似于以下所示。


在浏览器中模拟图层动画

实现这种用于获得随机值的系统的代码并不特别复杂。 它包括使用各种延迟的动画说明。 这是代码:

/*    z-index —     . */ @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; } /* -         z-index */ label:active::before {  content: "";  position: absolute;  top: 0;  right: 0;  left: 0;  bottom: 0;  z-index: 10; } 

这是一个实施此解决方案并使用更快动画的项目。

在对项目进行更改后,我只需要将自己的成就添加到游戏中即可。 就是我得到的。


成品游戏

该方法的缺点


此处描述的随机方法有明显的不便之处:

  • 因其工作需要用户参与。 该人员必须单击标签才能启动“生成随机值”的过程。
  • 它的伸缩性不好。 此方法非常适合处理少量值,但是如果需要从较大范围中获取随机值,则使用它非常不便。
  • 它的应用程序允许获取的不是随机值,而是伪随机值。 关键是计算机可以很容易地发现某个时间点将发出什么“随机”值。

总结


尽管存在上述局限性,此处介绍的方法还是基于纯CSS。 要使用它,不需要预处理器或某些外部辅助机制。 对于用户来说,它的使用看起来就像程序产生完全随机数一样。

顺便说一下,该方法不仅适用于生成随机数。 它允许您随机化任何东西。 例如,在项目中,它基于计算机在“石头,剪刀,纸”游戏中做出的“随机”选择。


纯CSS游戏“石头,剪刀,纸”

亲爱的读者们! 您是否打算在项目中使用本材料中突出显示的想法?


Source: https://habr.com/ru/post/zh-CN474310/


All Articles