September 27, 2019
CSS Custom Properties (Variables)
CSS Custom Properties is the formally correct name for the more commonly used synonym CSS variables. In this article we want to give you an insight how CSS variables help you to make CSS files more structured and semantically understandable, and how to modify them easily with JavaScript.
Documents or applications of any size contain many lines of CSS code. For example, the same color might be used in hundreds of different places, requiring global search and replace if that color needs to change. With CSS custom properties cascading variables can be defined as new primitive value type. They’re typically used to store colors, font names, font sizes, length units, etc.
Compared to preprocessor variables like Sass or Less, which have to be compiled into normal CSS to be read by the browser, CSS variables are real live CSS properties running in the browser. They can be changed in: Stylesheet documents, inline style attributes, SVG presentational attributes, media queries, animations and transitions. All this can also be manipulated via JavaScript. This opens up a whole world of possibilities!
However, this does not mean that you have to choose between one or the other. Take advantage of the CSS variables and preprocessor variables and let them work together.
Browser Support
(references: BrowserSupport 20.09.2019 https://caniuse.com/#search=css%20variables)
Syntax
Initialize variable:
Custom properties starts with two hyphens (-) like --color
.
1 |
element { --color: red; } |
and accessed using var()
:
1 2 3 |
element { color: var(--color); } |
Attention: unlike other CSS properties, custom properties are case-sensitive!
For instance, var(--foo)
and var(--FOO)
refer to two different custom properties, --foo
and --FOO
respectively.
Custom properties are inherited. This means that if no value is set for a custom property on a particular element, the value of the parent element is used. As the following example illustrates:
1 2 3 4 5 6 7 8 9 10 11 |
:root { --color: blue; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } <p>I inherited blue from the root element!</p> <div>I got green set directly on me!</div> <div id='alert'> While I got red set directly on me! <p>I’m red too, because of inheritance!</p> </div> |
CSS Variables in JavaScript
In JavaScript there are many methods (see references) to use the values of custom properties. It is useful to know that JavaScript initialized the variable in HTML as inline style.
In this CodePen example the variable --color
is globally initialized.
After clicking the button the color changes to blue.
With setProperty('--color', 'blue')
the following was initialized in the HTML file:
1 |
<html style='--color:blue;'> |
With removeProperty('--color')
this inline style is deleted from the html file and the value initialized in the CSS file is used again.
Now that we know how JavaScript handles the variables we have to consider the following with the getPropertyValue()
method.
1 2 |
// get variable from inline style document.documentElement.style.getPropertyValue('--color') |
If you call getPropertyValue()
before you set it with JavaScript. You get the value “null”, because there is no inline style defined in the HTML file.
After you have clicked the button you get the value blue.
Workaround (getting styles like this wouldn’t be considered best practice):
1 2 3 4 5 |
// get variable from wherever (But be careful with this, because its computed!) getComputedStyle(element).getPropertyValue('--color'); // queries the value of the --color property in a CSS selector rule document.styleSheets[0].cssRules[0].style.getPropertyValue('--color'); |
Fallback and Invalid variables
As fallback, a unique definition after the CSS variable can be noted:
1 |
element { color: var(--color, red); } |
The CSS function var()
contains a comma-separated fixed value in addition to the variable name. If the variable does not exist, it is used.
Attention: Older browsers that do not understand var() also ignore this statement.
When the browser encounters an invalid var()
substitution, the initial or inherited value of the property is used, going back to the browser’s default settings.
Internet Explorer integration
CSS Custom Properties (Variables) are not supported in Internet Explorer, it is possible to use a postCSS plugin that adds the property with its value to each element.
https://github.com/postcss/postcss-custom-properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
:root { --color: red; } h1 { color: var(--color); } /* becomes */ :root { --color: red; } h1 { color: red; color: var(--color); } |
References
- CSS Variables: https://www.w3.org/TR/css-variables-1/
- JavaScript Methodes for CSS Variables: https://www.w3.org/2003/01/dom2-javadoc/org/w3c/dom/css/CSSStyleDeclaration.html?is-external=true