So I made this example: https://jsbin.com/meqibawotu/1/edit?html,css,output
We have two "toggle vars", `--is-hovered` and `--is-special`, which are triggered by a hover selector and a class, respectively, though they could be triggered by anything (like a media query or JS).
The "false" value for the toggle is "initial", so at the top I set:
div {
--is-hovered: initial;
--is-special: initial;
}
The first trick is that assigning a variable value as a single space token is valid according to spec (https://www.w3.org/TR/css-variables-1/#syntax), making the var(...) usage substitute a single space. So if our variable should be "true", we use whatever method to set it to a single space: div:hover {
--is-hovered: ;
}
div.special {
--is-special: ;
}
The second trick is that an invalid property value will fall back to the second argument of the `var()` function. So we first create a property that only has a valid value if the flag is true (a single space): --hover-opacity: var(--is-hovered) 1.0;
If the div is hovered, `--is-hovered` is a single space, so the property value becomes: --hover-opacity: 1.0; // note two spaces
If the div isn't hovered, `--is-hovered` is `initial`, so the property value becomes: --hover-opacity: initial 1.0;
Which is invalid CSS!We can then interpret this in our final opacity property:
--regular-opacity: 0.5;
--opacity: var(--hover-opacity, var(--regular-opacity));
If the div is hovered, the first argument is evaluated to: --opacity: var( 1.0, var(--regular-opacity));
And since that's valid syntax, the second argument is short-circuited (ignored). However, if the div isn't hovered, then the opacity property is computed as: --opacity: var(initial 1.0, var(--regular-opacity));
The first argument is invalid! So the property falls back to the second argument, and we get `var(--regular-opacity)`.