Search code examples
csscss-cascade

Overriding CSS property all: unset


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?


Solution

  • 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.