For a CSS framework I am developing, I am using all: unset
, which by itself works fine:
#foo { all: unset; }
However, in certain cases, I want to "undo" the effect of this rule, as in
#foo:hover { all: auto; }
However, this obviously does not work because there is no value of auto
for all
. Instead, we have the values inherit
and initial
, which instead of "cancelling" the all
property, have different effects: of reverting all values to their parent's value, or their initial (I assume this means system-level default values).
To accomplish what I want, I am currently doing
#foo:not(:hover) { all: unset; }
which works fine, but is not too scalable if I want to do this for multiple pseudo-classes, for example, and I would prefer to override the all: unset
property? Is there any way to do so?
It does not appear to be possible to undo the effects of the all
property once it has been specified. This may be due to all
being a shorthand property (that happens to accept only the CSS-wide keywords as values).
You can't erase a shorthand declaration from the cascade the same way that css-cascade-4's introduction of the revert
keyword allows you to erase author-level declarations, and that's because a shorthand property doesn't exist as its own entity in the cascade; instead, it simply represents all of its component properties. Like with the more traditional shorthand properties such as background
and font
, the only way to override a shorthand declaration that has been applied is to re-specify the values for the longhands that were overridden, either via longhand declarations or via another shorthand declaration. But you can't do the latter with the all
property since it only accepts CSS-wide keywords.
As the former is obviously not practical with the all
shorthand, since you can't predict which author-level declarations are being overridden to begin with, your only other option is to restrict it via a selector, thereby preventing it from ever applying in specific circumstances in the first place. Hopefully we will see more implementations of level 4 :not()
in the near future, which will make writing selectors a little easier.
Additionally to what BoltClock explained, what you want is not currently possible even for non-shorthand properties.
* { color: red; }
#foo { color: unset; }
#foo:hover { color: /* How to revert to red? */ }
Once you add a value which wins the cascade, there is not way to tell the cascade to "go back" and get the previous winner instead. You must set it explicitly, but that's only possible if you know it.
The closest thing is the revert
keyword, introduced by CSS Cascade 4, which rolls back the cascade to previous origin level. But rolling the cascade back to the previous winner in the same origin level is currently not possible.
Then, the solution is restricting your selectors to apply only when you want them. This way there is no need to undo.