Are there random numbers in CSS?

CSS allows you to create dynamic page layouts and web project interfaces. But CSS is a static language. After a certain value is set, it cannot be changed. The idea of ​​randomly changing certain values ​​is not considered here.







Random number generation is a territory of JavaScript that CSS does not enter. But what if this is not entirely true? In fact, if you take into account the actions performed by the user, this will add a bit of randomness to the CSS. The author of the material, the translation of which we publish today, suggests discussing this.



External CSS randomization



You can use CSS variables to implement something like “dynamic randomization” in CSS. Here is some good stuff about it. However, such solutions to the problem are not pure CSS. Here you need to resort to JavaScript features for writing new random values ​​to CSS variables.



You can use preprocessors like Sass or Less to generate random values. But after compiling and exporting the CSS code, these values ​​are fixed and the random element is lost. In one tweet on this topic, this approach to setting CSS values ​​is compared with a random choice of the name of the hero of the novel, which, once written on paper, has not changed.



Why am I interested in using random values ​​in CSS?



Once I was developing simple applications based solely on CSS. This is a quiz , a game of Simon and card tricks . But I wanted to do something more complicated. I do not touch upon questions of the correctness of this approach, questions of the utility or practical applicability of projects based solely on CSS.



Based on the premise that some board games can be represented as Finite State Machines (FSMs), we can conclude that such games can be implemented using only HTML and CSS. Armed with this idea, I started developing the game “ Snakes and Ladders ”. This is a simple game. Her goal is to throw a dice and arrive from the starting point of the playing field to the final one, while avoiding snakes and trying to use the stairs.



It seemed to me that this project could be done in HTML and CSS. However, I did not take into account something. It's about dice.



The roll of the dice (as well as the roll of the coin) are universally recognized as “generators” of random values. Each time, throwing a bone or coin, we get something that was previously unknown to us.



Dice throw imitation



I was going to superimpose layers with labels and use CSS animation in order to “scroll” them, changing the top layer. It looked something like the one below.









Simulate layer animations in a browser



Code that implements such a system for obtaining random values ​​is not particularly complicated. It includes a description of the animation using various delays. Here is this code:



/*    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; }
      
      





Please note that the animation was slowed down so that it would be easier to interact with the corresponding elements (but it turned out to be fast enough to cause a problem, which will be discussed below). Here the pseudo-random nature of the mechanism presented is clearly visible.



Here is a CodePen project that allows you to explore this approach





Dice throw imitation



Actually, here I ran into a problem. My program gave out random values, but sometimes, even when I clicked on a button simulating a bone throw, the system returned nothing at all.



I tried to increase the animation time, which seemed to me to slightly improve the situation, but the system still behaved incorrectly.



It was then that I did what all programmers do, faced with a problem that they cannot solve with a search engine. I asked a question on StackOverflow.



To my happiness, they explained everything to me, and suggested a solution to the problem.



A simplified description of my problem can be represented as follows: "The browser fires the click



event of an element only when the element that is active at the time the mousedown



event occurs remains active when the mouseup



event occurs."



Since the elements constantly replace each other - the top element on which the mousedown



event occurs when the mouse button is pressed is not always the same element on which, when the button is mouseup



event occurs. In order for the button to be pressed and released at the moment when the same element is at the top of the stack, the click must be performed either quickly enough (so the element does not have time to leave the top of the stack), or rather slowly (so the element there is a chance to return to the top, making a full circle). That is why an increase in the time of animations allowed to mask the problem.



The solution was to use the static



value for the position



property of the active element, which removed it from the stack of elements. Further, a pseudo-element, such as ::before



or ::after



, which was assigned a very large z-index



value, took its place. With this approach, the active element would always be at the top of the stack when releasing the mouse button.



 /*           */ 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; }
      
      





Here is a project that implements this solution and uses faster animation.



After I made this change to the project, I just had to add my achievements to the game. That's what I got.









Ready game



Disadvantages of the method



The random method described here has obvious inconveniences:





Summary



The method presented here, despite the limitations described above, is based on pure CSS. To use it, no preprocessors or some external auxiliary mechanisms are needed. And for the user, its use looks as if the program produces completely random numbers.



And by the way, this method is not only suitable for generating random numbers. It allows you to randomize anything. For example, in this project, it is based on a “random” choice made by the computer in the game “Stone, Scissors, Paper”.





The game "Stone, scissors, paper" in pure CSS



Dear readers! Do you plan to use the ideas highlighted in this material in your projects?








All Articles