@andruud
CSS has built-in mechanisms for falling back to a previously specified value whenever an invalid value is encountered. For example:
div.basic {
display: block;
}
div.fancy {
display: fancy;
}Given <div class="basic fancy">, and assuming that fancy is not (yet) a valid display type in your user agent, the display: fancy declaration is simply ignored; we effectively fall back to display: block.
This fallback functionality depends on declarations being recognized as valid or invalid at parse time. With the proliferation of
arbitrary substitution functions, however, this is no longer possible, since values containing such functions are assumed to be valid at that time. For example, say we want to make display fancy conditionally
based on a custom property:
div.basic {
display: block;
}
div.fancy {
display: if(style(--enable-fancy): fancy);
}If --enable-fancy is not set here, we do not fall back to block; it instead becomes invalid at computed value time, and ultimately the property's initial value (inline). While you could provide your fallback as an else:block branch to the if() function, this requires providing the block value explicitly; you lose the flexibility inherent in the behavior of falling back to whatever you would otherwise get (without knowing the details).
The revert-rule keyword allows authors to dynamically revert back to the previous rule in the sorting order
determined by css-cascade:
div.basic {
display: block;
}
div.fancy {
display: if(style(--enable-fancy): fancy; else: revert-rule);
}When --enable-fancy is not set, the revert-rule in the else branch effectively eliminates the declaration, and reverts back to whatever value would otherwise win the cascade for display. In this simple case, that is block from div.basic, but in a more complicated example, the reverted-to value could vary based on a number of CSS style rules and conditionals.
It's worth noting that it's already possible to effectively get revert-rule-like behavior by wrapping declarations in an anonymous layer and using revert-layer instead:
div.fancy {
@layer {
display: if(style(--enable-fancy): fancy; else: revert-layer);
}
}The revert-rule keyword may therefore be seen as an author convenience to achieve what can currently be achieved with anonymous layers and the revert-layer keyword.
Although this is already valuable enough from an ergonomic perspective, the higher-level CSS concepts that could be unblocked by revert-rule's underlying behavior are perhaps more exciting:
- A conditional
@ifblock rule, Issue 12909. - Additive styling via an equivalent functional notation (
revert-rule()). For example,div { --foo: revert-rule(--foo) bar; }would appendbarto the previous value of--foo.
There are no known security or privacy concerns. The revert-rule is functionally equivalent to behavior that is already possible in a more verbose way (see previous section).
- CSS Values 5 Specification
- Issue 10443 (original proposal)