DEV Community

Peter Weightman
Peter Weightman

Posted on

Randomising CSS with CSS Variables and JS

Intro

I was watching The Salisbury Poisonings TV show and the credits caught my eye. Behind the actor’s/actress’s names was a box that looked like it was randomly translated/rotated and I wanted to try and recreate the effect on codepen.

Desired Effect

Alt Text

Final Result

How it was done

HTML

First I made the markup which you can see in the codepen, it was a list, and in each list item was a key and value.

CSS

For the layout, I made the main container display flex so that I could easily center the list, and then I made each list item a grid with two equal columns.

For the white background behind the ‘value’ divs, I used a pseudo element positioned absolutely to the same size as the div and then put behind the text with a negative z-index.

Now for the randomness, I made a -—random variable initialised to 0. Then on the pseudo element background I added:

transform: scale(1.15) translate(calc(var(--random) * 4px), calc(var(--random) * 2px)) rotateZ(calc(var(--random) * 2deg));

This scaled it up so that I had a bit of a buffer to be able to translate/rotate it and keep it behind the text. Then I translate and rotate using calcs and my variable.

Javascript

Now at this point, because the variable is initialised to one, the background will only be scaled and look the same for all of them. This is where some javascript comes in.

function randomise() {
  document
    .querySelectorAll('.value')
    .forEach(el => {
      el.style
        .setProperty(
          '--random',
          Math.random() * 2 - 1
        );
    });
}

This sets the CSS variable on each ‘value’ div to a random number between -1 and 1, which is then used in the transforms.

I call this function on initial load and also if you press the randomise button.

Conclusion

I’m pretty happy with how it turned out. It’s a shame there’s no built in css random number generator (as far as I’m aware) but with a small amount of js we’re able to achieve the same effect!

Oldest comments (0)