Getting to grips with CSS variables
If you have ever used JavaScript variables then the concept of CSS variables should feel pretty familiar.
- You set a variable
- You use the variable
CSS variables follows this same pattern, but the language is slightly different.
body {
--my-variable: red;
}
h1 {
color: var(--my-variable);
}
What is happening here? Firstly we set the variables - essentially they are custom properties. We use --
before the variable name to make it a variable. Then we use the variable by using var(--variable-name)
.
<body> <!-- --my-variable: red; -->
<h1>CSS - Carl's Super Styles!</h1> <!-- colour: red -->
</body>
Usually most variables are set on the pseudo element ::root
so that every HTML element will be encompassed by it.
:root {
--color: red;
--size: 20px;
--background: #222;
--padding: 1em;
}
Scope of variables
CSS variables are scoped to their ancestors (parents, though grandparents to the root pseudo element).
Variables can be changed by child elements, but only apply further downstream in the DOM. That means that variables set in different branches of the DOM are only applicable to that tree. A bit like genetics, you only share the same genes from shared ancestors.
Changing a variable
:root {
--my-variable: red;
}
body {
--my-variable: blue;
}
h1 {
color: var(--my-variable);
}
Here the root color of red is overridden by the my-variable
on the body, so the h1
ends up with blue text.
<!-- :root --my-variable: red; -->
<body> <!-- --my-variable: blue; -->
<h1>CSS - Carl's Super Styles!</h1> <!-- colour: blue -->
</body>
The Same variable in different trees
In the following example the root --color
variable is black. We then set the classes of .red
and .blue
to red and blue respectively. Then we create a h2
to consume the --color
variable.
:root {
--color: black;
}
.red {
--color: red;
}
.blue {
--color: blue;
}
h2 {
color: var(--color);
}
The h2
that is not wrapped by either one of red
or blue
inherits the value for the root color variable which is black. Both red
and blue
redefine the value of the variable and the h2 within their trees will be the relevant color.
<h2>Black</h2>
<div class="red">
<h2>Red</h2>
</div>
<div class="blue">
<h2>Blue</h2>
</div>
Media queries
In the pre variable days of css we did this:
.red {
font-size: 1em;
}
.blue {
font-size: 1em;
}
@media screen and (min-width: 32em) {
.red {
font-size: 2em;
}
.blue {
font-size: 2em;
}
}
With variables we can replace the hardcoded values with values set at the :root
.
:root {
--mobile-size: 1em;
--desktop-size: 2em;
}
.red {
width: var(--mobile-size);
}
.blue {
width: var(--mobile-size);
}
@media screen and (min-width: 32em) {
.red {
width: var(--desktop-size);
}
.blue {
width: var(--desktop-size);
}
}
We can do one better and move the mediaqueries to the root, cutting out the need to add extra code for developers to maintain. Mediaqueries can then all be managed in 1 place too!
:root {
--font-size: 1em;
}
@media screen and (min-width: 32em) {
:root {
--font-size: 2em;
}
}
.red {
width: var(--font-size);
}
.blue {
width: var(--font-size);
}