Javascript 30 — Day 3: CSS Variables & JS

Mike Ekkel
4 min readJan 16, 2017

--

Yesterday I played around with adding inline styles using JavaScript to create a working clock. We’re continuing the use of CSS today as we create an image editor… thingy. Yeah, let’s stick with that.

Check out all the other days over at my table of contents!

The image editor thingy!

Alright so first things first: CSS variables, or Custom properties, are brand spanking new and after using them for a whopping two minutes, I love and hate them. They finally bring the power of variables to CSS without the use of CSS-preprocessors. Why do I hate them? Well I’ll show you:

:root {
--base: #00D8FF; /* Mike 'Murkrage' Ekkel blue ;) */
--spacing: 10px;
--blur: 10px;
}

Maybe hate is a strong word, but using dashes for variable names? Really? That’s what they went with. Ah well, can’t have it both ways I suppose.

Okay so what’s going on there. Well we’re applying the variables to the root of our document by selecting :root which, if you’re unfamiliar with, is actually a pseudo-class to select the root element of the document. Then we set the variables as we normally would, well with dashes this time, and we can use them anywhere we like.

img {
padding: var(--spacing);
background: var(--base);
filter: blur(var(--blur));
}

Yeah okay so that’s another reason; when referencing the variable you also use the dashes inside the var() function. But other than that, it looks great!

Okay onwards to the JavaScript code, which is why you are reading this:

document.querySelectorAll('.controls input')

It’s day 3 now and I am starting to get very familiar with querySelector and querySelectorAll . Today, however, Wes kindly explained that the latter returns a NodeList and not an Array. It’s very much like an Array, but it’s not. It’s only got a few methods that we can use, like forEach . I recommend reading the MDN entry about NodeLists to learn more. It’s a tiny article, I’ll still be here so go on and read it :).

Now that we have a list of all of the inputs we need to see if any of them are being changed. As you might have guessed, we are using the addEventListener method to do that.

function handleUpdate() {
console.log(this.dataset.sizing)
}
inputs.forEach(input => input.addEventListener('change', handleUpdate))

side note: the this.dataset property returns a DOMStringMap, let’s just call it an Object, that holds all of the data- attributes. The custom ones we add to our HTML elements.

Now that we can listen to change, Wes points out that it’s no happening live. It’s happening on change as it should, but the actual changing doesn’t happen until we let go of the cursor. So to fix this we add a mousemove event listener.

inputs.forEach(input => {
input.addEventListener('change', handleUpdate);
input.addEventListener('mousemove', handleUpdate);
}

Wes has written it a little different as he just copied the previous line and changed it to mousemove but I like the readability of my code a little better. I’m not sure what the performance impact is, but it works as intended.

To now change the variables, or custom properties, based on the inputs we call the setProperty method on the root element:

document.documentElement.style.setProperty()

The method takes in the property that we want to change and the value we want it to hold. Our entire function looks like this:

function handleUpdate() {
const suffix = this.dataset.sizing || '';
document.documentElement.style.setProperty(
`--${this.name}`, this.value + suffix
)
}

The suffix is there to get the sizing from the HTML element. In this case we need it to say px for the blur and border. We get the values from the dataset which holds data-sizing for all the inputs.

TIL (Today I Learned)

  • CSS has variables (I had no idea)
  • All of the data attributes can be accessed using dataset
  • QuerySelectorAll returns a NodeList, which is kind of like an Array, except that it’s not
  • CSS Custom Properties can be changed using the setProperty method

Today’s project was another small one to get you tinkering with a few old things (old as in day 1 and 2) and introduce a few new things. I think it’s great that it shows that having a simple input based application can be easily achieved using a couple of sliders and about 7 lines of code.

All of my code can be found at GitHub.

Check out all the other days over at my table of contents!

Wes is an amazing teacher. If you want to become more comfortable with Javascript, go check out his free course at javascript30.com.

Until next time!

--

--

Mike Ekkel

Frontend developer from Rotterdam, the Netherlands. Currently @ Bynder. Follow me on twitter @Murkrage.