The surprising behavior of "important CSS custom properties"
- Published at
- Updated at
- Reading time
- 3min
CSS custom properties are flexible, make code DRY ("don't repeat yourself"), and can keep a codebase maintainable. The larger a CSS codebase, the more critical your CSS is easy to handle. CSS code becomes messy when you add new code without having a strategy, but if you throw !important
into the mix, a maintenance nightmare is often unavoidable.
But have you tried using !important
with custom properties? You'll find Interesting things!
Be warned, the !important
keyword in custom properties declaration behaves differently than you think!
The syntax for custom property values is permissive. The specification allows everything but a few specific tokens as the custom property value. These prohibited tokens include unmatched ]
or }
, semi-colons or the !
character.
Even though !important
obviously includes a !
, it's considered a special case that is still valid!
HTML
CSS
As you see in the example above, the color
property is parsed and applied correctly. That's great news, but be aware that !important
in custom property values comes with surprising behavior.
If you have another look at the spec, you'll find this note:
Custom properties can contain a trailing !important, but this is automatically removed from the property’s value by the CSS parser, and makes the custom property "important" in the CSS cascade.
!important
is removed from the property value? Does that mean you can overwrite an applied "important CSS custom property" with another CSS property? Jup, it does!
HTML
CSS
But the spec defines that a custom property including a trailing !important
is marked "important" in the CSS cascade; what's that about then?
Custom property declarations are handled similar to "normal CSS declarations". The CSS cascade is used to evaluate a custom property's value when there are multiple custom property declarations.
HTML
CSS
Above, the custom property declaration with the highest specificity (the !important
one) wins and defines --color
.
When the --color
custom property is used, it remains that !important
is not set as a property value for color
. As Šime Vidas pointed out, !important
is only used to determine the value of a CSS declaration using the CSS cascade and not available at later stage.
This means, you can still overwrite color
with other color
declaration (no matter if it was defined using an "important custom property" or not).
HTML
CSS
That's confusing stuff! 🤯
I stand by it: it's best to avoid !important
and if you really have to use it, consider it very carefully. And honestly, I wouldn't mix !important
into custom property values because this surprising "quirk" is very hard to spot!
Join 5.5k readers and learn something new every week with Web Weekly.