The power of CSS variables
CSS variables are the next big thing and their power is often underestimated. People call them “CSS variables”, which doesn’t describe their actual behavior properly. CSS Custom Properties — as the specification names them — can do much more for you than SASS variables. They’re properties and they cascade like normal properties.
I’ve made a test project to learn more about them and tried not to use any SASS variables at all. Here’re some of the benefits I discovered:
Eliminate redundant styling
The principle you know from functions in programming languages applies to CSS Custom Properties: Define once, reuse often. No need to write the same code over and over again 😌
Before
.button {
display: inline-block;
padding: .5em 1em;
color: white;
}.button--red {
background: red;
box-shadow: inset 0 0 2px red;
}.button--blue {
background: blue;
box-shadow: inset 0 0 2px blue;
}
After
.button {
display: inline-block;
padding: .5em 1em;
color: white;
background: var(--color);
box-shadow: 0 0 2px var(--color);
}.color-red { --color: red; }
.color-blue { --color: blue; }
The new approach brings several advantages:
- All button styles are now in one place
- Redundant styling has been removed
- Color classes can be used for all elements with dynamic colors
You can even define a fallback value for all your buttons 🤘
background: var(--color, black);
box-shadow: 0 0 2px var(--color, black);
Conditional values
Custom properties can be made conditional with @media
and @supports
. Changing a variable in a conditional rule affects the properties in which you’ve used the variable. It’s the same behavior as in the previous example. Just with conditional rules.
.warning {
display: var(--display, none);
background: red;
}.warning::before {
content: 'Your browser does not support ' var(--feature) '.';
}@supports not (display: flex) {
.warning {
--display: block;
--feature: 'CSS Flexbox';
}
}@supports not (display: grid) {
.warning {
--display: block;
--feature: 'CSS Grid Layout';
}
}
A bridge between HTML and CSS
It’s possible to define CSS Custom Properties in the HTML style attribute to use them in your CSS. Think about an element with a gradient, where the first color is always different. You could apply a gradient using JS or inline styles, but this would either cause a flash of unstyled content or HTML that contains styling.
Before
<!-- HTML -->
<div class="gradient" style="background: linear-gradient(to bottom, red, blue)"></div>
<div class="gradient" style="background: linear-gradient(to bottom, yellow, blue)"></div>/* CSS */
.gradient {
width: 100%;
height: 100px;
}
After
<!-- HTML -->
<div class="gradient" style="--color: red"></div>
<div class="gradient" style="--color: yellow"></div>/* CSS */
.gradient {
width: 100%;
height: 100px;
background: linear-gradient(to bottom, var(--color), blue);
}
It’s not only easier to read, it also improves the code quality and clarity:
- The gradient definition is back in the CSS file where it belongs to
- Redundant styling has been removed from the HTML
JS controlled variables
CSS Custom Properties can be used in calc()
functions to perform a calculation with them. That’s cool, but what if you want more power? JavaScript to the rescue! 💪
JS allows to read and write CSS variables. This gives you all the capabilities of a programming language to generate the content of your variables. It’s so powerful, you can even build a parallax scrolling library with it.
Here’s a demo combing CSS Custom Properties with JavaScript to generate a random gradient on the client-side:
Conclusion
Custom properties are way more than SASS variables. I highly recommend to play around with them in a project. Developing a complete page with them gives you a much better feeling than a simple CodePen experiment. Try to avoid SASS variables to see what you can and can’t do with CSS variables.