(I always wanted to do a clickbait title like this and when this chance came along I could not pass it up. 😅 Sorry!)
While putting my ideas into slides for my Dynamic CSS workshop for next week, I was working on a slide explaining how the CSS wide keywords work with custom properties.
unset I had used numerous times and knew well. But what about
revert? How did that work? I had an idea, but quickly coded up a demo to try it out.
The code was:
background: var(--accent-color, orange);
Phew, I was correct, but the amount of uncertainty I had before seeing the result tipped me that I might be on to something.
Before you read on, take a moment to think about what you would vote. Warning: Spoilers ahead!
So I posted a quiz on Twitter:
These were the results after the 24 hours it ran for:
orange was the clear winner, and the actual correct answer,
skyblue only got 18.1%, nearly the same as
If you got it wrong, you’re in very good company: not only did 82% of poll respondents get it wrong as well, but even the editor of the CSS Variables spec and co-editor of CSS Cascading and Inheritance (which defines
revert), Tab Atkins, told me privately that he got it wrong too: he voted for
orange! (Yes, I did get his permission to mention this)
So what actually happens? Why do we get
skyblue? I will try to explain as best as I can.
Let’s start by what
revert does: It reverts the cascaded value of the property from its current value to the value the property would have had if no changes had been made by the current style origin to the current element.
This means it cancels out any author styles, and resets back to whatever value the property would have from the user stylesheet and UA stylesheet. Assuming there is no
--accent-color declaration in the user stylesheet, and of course UA stylesheets don’t set custom properties, then that means the property doesn’t have a value.
Since custom properties are inherited properties (unless they are registered with
inherits: false, but this one is not), this means the inherited value trickles in, which is — you guessed it —
skyblue. You can see for yourself in this codepen.
What if our property were registered as non-inheriting? Would it then be
orange? Nice try, but no. When we register a custom property, it is mandatory to provide an initial value. This means that the property always resolves to a value, even
--accent-color: initial does not trigger the fallback anymore. You can see this for yourself in this codepen (Chrome only as of May 2021).