The surprising behavior of !important in CSS custom property values

Avatar of Chris Coyier
Chris Coyier on

Huh! I did not realize that CSS custom properties had their own resolution behavior for how !important works in their values. Uh, despite writing a guide about them. 😬 But hey it’s now updated.

Stefan Judis documents it clearly. The deal is that !important is not at all used in the final value. So:

div {
  --color: red !important;
  color: var(--color);
  color: yellow;
}

It kinda feels like red should win, but because !important is ultimately stripped from the custom property value, yellow wins it out. And it’s not because the color declaration comes last — if color: red !important; was the first declaration, then red would win.

But it’s not like !important is just stripped and ignored; it’s used in a scoped way, affecting which custom property value wins. But then !important is gone when that value is applied. Stefan’s example:

div {
  /*
    `!important` overrules the
    other `--color` definitions
  */
  --color: red !important;
  color: var(--color);
}

.class {
  --color: blue;
}

#id {
  --color: yellow;
}

This feels weird (to me) as you’d think yellow declared on #id would win because it has the highest specificity. But that’s the deal with the scoped behavior — !important makes red the winner, then is applied to the color as such.

Direct Link →