This is day 3 in my #javascript30 journey. This is the free course from Wes Bos that lets you brush up on your JavaScript skills via 30 projects.
Yesterday we built an analog clock. You can keep track of all the projects we’re building here.
Today we’re exploring scoped CSS variables and JS.
Day 3 - Scoped CSS Variables and JS
Today we are exploring CSS Variables. These can be made even more powerful by coupling them with JavaScript to update the values after the initial rendering.
Our exploration will give the end user three inputs where they can edit the spacing, blur and colour of elements within the page. This is a simple example but it is easy to consider how this can be altered and extended for some real use cases.
Our starter file for today looks like this:
Defining the CSS Variables
To do this first define the default variables on the root element:
:root {
--base: #FFC153;
--spacing: 10px;
--blur: 10px;
}
Once these variables have been defined we can start using them:
img {
padding: var(--spacing);
background-color: var(--base);
filter: blur(var(--blur));
}
Now our page has these styles applied and looks like this:
Gathering Data from Inputs via JS
To grab the data from the inputs we need to capture them into a variable. As we will be using the querySelectorAll syntax which will return a NodeList. This looks a lot like an Array but doesn’t have the same methods available. This is why we will need to use forEach()
to loop over all of the inputs:
<script>
const inputs = document.querySelectorAll('.controls input')
function handleUpdate() {
//TODO
}
inputs.forEach(input => input.addEventListener('change', handleUpdate))
</script>
A range input outputs a numerical value. To insert this into our CSS we need to know the appropriate suffix for this number. For example, in our \--spacing
and \--blur
styles we need to know that this value is followed by px
. To handle this Wes created a data attribute on each of the inputs:
<input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">
Now in our handleUpdate()
function we can check to see whether sizings
is present in the dataset & if it is capture it:
const suffix = this.dataset.sizing || ``;
Selecting a CSS variable
Wes also added a handy name on our inputs so we can use these when selecting the style to update:
function handleUpdate() {
const suffix = this.dataset.sizing || ''
document.documentElement.style.setProperty(
`--${this.name}`,
this.value + suffix,
)
}
This is all of the code that we need to do to make our CSS variables update & change the page:
Now that everything has been done I have pushed this project live to a Firebase project. You can view it live here.
You can keep track of all the projects in this JavaScript30 challenge here.