It's "well known" that you can use a CSS variable to simplify writing properties that require browser-specific vendor prefixes. (See Lea Verou, "Autoprefixing, with CSS variables!".) For example,
* {
--clip-path: initial ;
-webkit-clip-path: var( --clip-path ) ;
clip-path: var( --clip-path ) ;
}
.maximalCircle {
--clip-path: circle(50%);
}
In this example,
--clip-path:initial;
cancels inheritance so an element will have a clip-path
value other than initial
(which equals border-box
) only if --clip-path
is defined within that element.--clip-path: circle(50%);
effectively sets the value for both the vanilla clip-path
and the WebKit-specific -webkit-clip-path
properties.You can see this in action at this Pen.
I'm failing, however, in using CSS variables to simplify a different property: the -webkit-background-clip
property: if I assign a CSS variable --clip-path:text;
as the value of the -webkit-background-clip
property, (a) Safari (and Firefox) like it fine but (b) Chrome doesn't understand it (i.e., the computed value in Chrome is background-clip: border-box
, which is the default value).
[In all these tests, I'm using Safari 12.1.1, Firefox Quantum 67.0.4, Firefox Developer Edition 68.0b12, and Chrome 75.0.3770.100.]
Cliff Notes for below minimum working example: A <div class="text-masked-gradient">
contains a text string, which sits on a gradient background. The CSS background-clip:text
(and/or -webkit-background-clip:text
) property should cause the background to show through only the text itself. The image below shows (a) what it looks like when it works (L) and (b) when it doesn't (R).
My HTML markup:
<div class="text-masked-gradient">
YELP
</div>
Full CSS is below. This code also exists at this Pen. (I consider many more scenarios, for diagnostic purposes, at this other Pen.)
The full CSS:
.text-masked-gradient {
--background-clip: text ;
-webkit-text-fill-color: transparent;
text-fill-color: transparent;
-webkit-background-clip: var( --background-clip );
height: 150px ;
width: 300px ;
outline: solid black ;
margin: 50px ;
font-size: 7em ;
text-align: center ;
font-weight: 700 ;
background-image:
radial-gradient(circle at top left,red,chartreuse);
}
This renders correctly in:
but not in
Am I doing something wrong? Is this a Chrome bug related to CSS variables and the -webkit-background-clip
property?
(This example works fine in all these browsers, including Chrome, if you use -webkit-background-clip:text
rather than webkit-background-clip:var(--background-clip)
.)
Lea Verou has confirmed that this is a Chrome bug. She created this reduced test case, which fails when viewed with Chrome. She filed this bug report: Issue 980439.
On top of that, there's a WebKit bug (thus affecting both Safari and Chrome) when you try to define the background-clip
property with a CSS variable, e.g., background-clip:--a
, where the CSS variable is text
. This causes both Chrome and Safari to ignore a valid -webkit-background-clip:text
rule. See Bug 199410 - background-clip:var(--a)
invalidates -webkit-background-clip:text
when --a:text
.
Due to both of these bugs, the background-clip
property isn't at this time a good candidate for using CSS variables to simplify vendor prefixes.