Caio Lente

Randomness with CSS

· Caio Lente

This page contains a simple D20 roller. Click on the hexagon below to get a random number and click again to clear the last result.


How it works

First off, I know you can just google “D20” and get a pretty animation that gives you a random number between 1 and 20. But where’s the fun in that? The gimmick of my dice roller is that is uses no JavaScript at all.

I don’t like JavaScript

If you don’t know what JavaScript is or why this matters, let me give you a quick summary: JS is one of the most popular programming languages in the world (it’s used on 98% of all websites!), and it allows your browser to do amazing things like log in to Gmail or run D&D over Roll20.

The problem is that JS is so awesome that people started using it everywhere. While you really do need JS in order to create dynamic webpages, it isn’t necessary in most places; the term “website obesity crisis” came to be used to describe the fact that most websites nowadays focus too much on fluff and unnecessary dynamism, and too little on content and accessibility.

I could go on about how JS makes webpages more insecure, how it’s usually overkill, and how it’s an unnecessary tax on people with slow connections, but I think you get my point. I wanted to create a lightweight dice rolled without JavaScript.

CSS to the rescue

Besides JS, another major component of web development is CSS, which describes how everything should look on the page. But what does this have to do with the dice roller? Well, for starters, CSS is super light and 100% secure, however it has a often overlooked feature called Animations.

I almost didn’t believe my eyes when I first read Creating randomness with pure CSS. The gist of the article is that you can use CSS to move an image back and forth behind a virtual slit and stop it only when the user clicks a button. If your image is a bunch of playing cards stitched together, only one of them will show through the slit once the animation stops.

The genius insight is that, if the animation is fast enough, the slight variations in the user’s clicks will effectively make the slit show a random card each time!

This was the JS substitute I needed. Now all I had to do was apply this method to a list of numbers instead of an image. It did take some time, but I scoured the web for a solution and eventually found it in iokaravas’ JS-free slot machine.

Their code takes three lists of numbers and animantes them up and down until they land on the combination set by the programmer. Despite being deterministic, this could seamlessly be integrated with Creating randomness’ technique to create exactly what you see at the top of this page.

Conclusion

TL;DR: in the dice roller above, there is actually an invisible list of numbers being animated up and down which stops when you click it. The randomness comes from the fact that it’s moving too fast for anyone to be able to time it.

A few key facts:

  1. It’s JavaScript-free. You can verify this for yourself by opening the Network tab on your browser and inspecting the source code for <script> tags.

  2. It’s light. While Google’s dice roller is 2.6MB and loads in 1.6s, this one is 7.1kB (~360x lighter) and loads in 50ms (~30x faster).

  3. It’s fair. I ran a Chi-squared test with 1000 samples taken at random time intervals and it is in fact fair (p = 0.7575).

Thanks for reading!

#web #stats