The surprising behavior of "important CSS custom properties"
- Published at
- Updated at
- Reading time
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!
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
}, semi-colons or the
!important obviously includes a
!, it's considered a special case that is still valid!
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:
!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!
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.
Above, the custom property declaration with the highest specificity (the
!important one) wins and defines
--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).
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!