Overriding CSS property all: unset
Asked Answered
B

3

6

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?

Bobine answered 8/4, 2016 at 9:36 Comment(0)
C
2

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.

Conard answered 8/4, 2016 at 9:46 Comment(0)
G
2

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.

Gunslinger answered 9/4, 2016 at 18:20 Comment(1)
"But rolling the cascade back to the previous winner in the same origin level is currently not possible." And the reason for this is because the cascade can't tell what the "previous winner" is in the first place. If it just assumed the order of declarations, specificity notwithstanding, that would be very error-prone.Conard
L
1

Have you tried

all: revert

More infos here MDN

Leafy answered 8/4, 2016 at 9:46 Comment(4)
That reverts values to their browser defaults, which is one of the things the OP is trying to avoid.Conard
Yes I know, but I don't know how they're handling the styles so they might have origins that permit the use of revert.Leafy
Yes, I saw revert, but besides not doing what I want, it is pretty much unsupported.Bobine
I've had a similar question and this helped with my issue How to prevent very generic CSS selector to interact with library CSS?. and in 2022 the support is pretty good.Synectics

© 2022 - 2024 — McMap. All rights reserved.