The whole world of conditional logic and bulk toggling in CSS only exists because of one tiny footnote in the CSS spec.
That line is:
Note: While must represent at least one token, that one token may be whitespace.
That means --foo: ;
is valid.
Now, this doesn’t read as some massive revelation that unlocks huge doors, but it is! Now we have the capability to make conditional statements all in CSS!
Here's a demo:
(Open the pen in a new tab and resize to see the full effect)
Let me explain:
- There is a breakpoint setup here at 350px. This is where the variable
--color
changes frominitial
to an empty space - When the browser window is wider than 350px, the value of
--color
isinitial
- That makes the variable
--color-when-small
contain two values:initial
andred
which is invalid. (This is not exactly correct and I'm writing it like this for simplicity. See this comment) - So when we actually set the color and call that variable like
background-color: var(--color-when-small, var(--color-when-big));
, the second value (the fallback) is used because the first is invalid.
- That makes the variable
- When the browser window is narrower than 350px, the value of
--color
is a space.- That makes the variable
--color-when-small
contain the value"(space)red"
, which is valid - So when we actually set the color and call that variable like
background-color: var(--color-when-small, var(--color-when-big));
, the first value is used
- That makes the variable
So, now we can flip the color between two values by changing a placeholder variable. I hope that clicks for you.
When we see this as simply changing a single value, it’s almost like ok, you’ve found a really complex way to change some padding, but you could have just changed the padding in the media query. But the trick is that now we have this placeholder variable that has changed and we can key into that to change unlimited other values.
We could have a single media query (or set of media queries) in our CSS that only toggles these placeholder variables and we use elsewhere to toggle values. That could be nice and clean compared to sprinkling media queries all over the CSS. It’s a proper toggle in CSS, like a form of IF/THEN logic that we haven’t quite had before.
For example, imagine we had a border for our earlier coloured div. Instead of changing the border directly in the media query, we can use the custom property again to change the border.
Here is an example:
(Open the pen in a new tab and resize to see the full effect)
If we were creating a complex card, this could come in handy.
This is not just for media queries. CSS trickery master Lea Verou has set her sights on this too:
What if I told you you could use a single property value to turn multiple different values on and off across multiple different properties and even across multiple CSS rules?
It’s the same trick!
This opens up a lot of possibilities in CSS. We could do AND, OR, XOR, NOR etc. with this trick. But I'm leaving that for you to find.
Thanks for reading!
Top comments (5)
That makes the variable --color-when-small contain two values: initial and red which is invalid --> this is false because the value will not contain initial. initial is not stored inside the
--color
variable. It's applied to--color
and is making the latter invalid which will also make any variable referencing--color
also invalid. (you can find the details here: w3.org/TR/css-variables-1/#using-v... note the is anything but the initial value) ... You also don't need to set--color:initial
since it's the default valueThanks! I didn't know that. Will update the post.
You can read the original, not plagiarized version here: css-tricks.com/the-css-custom-prop...
Your example is a bit overkill for a basic task. You can simply do the following: jsfiddle.net/4k9aj0zc/1/ .. you don't really need to make it complex with the empty var trick.
That is a nice approach, but it's almost similar to directly setting the property like
background-color: ...
in the media query.This is a basic demo but I added the complexity for understanding. I don't want people wondering "where did this undefined variable come from" etc.