cssbackgroundcss-variablesvendor-prefix

Using CSS variable to define -webkit-background-clip property doesn't work on Chrome


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,

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).

enter image description here

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).)


Solution

  • 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.