问题
I'm trying to change the selection color for an entire web page using a css variable:
html {
--my-var: red;
}
::selection {
background-color: var(--my-var);
}
<p>a b c</p>
<div>
<p>x y z</p>
</div>
I correctly see the selection styling applied. However if var
references a variable that is not defined, there is no selection color at all:
html {
--my-var: red;
}
::selection {
background-color: var(--not-my-var);
}
How can I define a selection color for an entire page that uses a css variable value if it is exists, or falls back to the default browser selection color? I've tried var(--not-my-var, unset)
, var(--not-my-var, inherit)
and var(--not-my-var, initial)
but they do not seem to work
回答1:
The only way to obtain what you want is to make sure the value is invalid so the browser will ignore it and fall back to the default one:
::selection {
background-color: something_invalid;
}
<p>a b c</p>
<div>
<p>x y z</p>
</div>
Unfortunately, this won't be possible when using var(--variable)
since the value will never be invalid.
From the specificatition we have the following steps to find the value:
To substitute a var() in a property’s value:
- If the custom property named by the first argument to the var() function is animation-tainted, and the var() function is being used in the animation property or one of its longhands, treat the custom property as having its initial value for the rest of this algorithm.
- If the value of the custom property named by the first argument to the var() function is anything but the initial value, replace the var() function by the value of the corresponding custom property.
- Otherwise, if the var() function has a fallback value as its second argument, replace the var() function by the fallback value. If there are any var() references in the fallback, substitute them as well.
- Otherwise, the property containing the var() function is invalid at computed-value time.
(2) and (3) are trivial and will always give us a value. (1) tell us to treat the value of the custom property as initial
and we will fall into (3) or (4).
For the (4) we can also read from the same specification:
A declaration can be invalid at computed-value time if it contains a var() that references a custom property with its initial value, as explained above, or if it uses a valid custom property, but the property value, after substituting its var() functions, is invalid. When this happens, the computed value of the property is either the property’s inherited value or its initial value depending on whether the property is inherited or not, respectively, as if the property’s value had been specified as the unset keyword.
background-color
is not inherited so it will use its initial value which is transparent
that's why you see no color.
Now if we consider the fallback cases (3)
- using
initial
means the initial value of background color so transparent - using
inherit
means inherit the color but there is nothing to inherit so transparent again - using
unset
we will have a mix ofinherit
andinitial
The unset CSS keyword resets a property to its inherited value if it inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, and like the initial keyword in the second case ref
Your only chance would probably be the use of revert but the support is very low and I am not sure if it will work.
The revert CSS keyword reverts the cascaded value of the property from its current value to the value the property would have had if no changes had been made by the current style origin to the current element. Thus, it resets the property to its inherited value if it inherits from its parent or to the default value established by the user agent's stylesheet (or by user styles, if any exist). ref
Update
As per the comments below, it seems also impossible with revert
.
来源:https://stackoverflow.com/questions/56798646/css-selection-with-var-fallback