+201223538180

Web site Developer I Advertising and marketing I Social Media Advertising and marketing I Content material Creators I Branding Creators I Administration I System SolutionThe Huge Gotcha With Customized Properties

Web site Developer I Advertising and marketing I Social Media Advertising and marketing I Content material Creators I Branding Creators I Administration I System SolutionThe Huge Gotcha With Customized Properties

Web site Developer I Advertising and marketing I Social Media Advertising and marketing I Content material Creators I Branding Creators I Administration I System Resolution

I’ve seen this confuse greater than a handful of individuals not too long ago, together with myself, so I’m ensuring it’s written down.

Let’s chuck a few customized properties into CSS:

html {
  --color-1: crimson;
  --color-2: blue;
}

Let’s use them immediately to make a background gradient:

html {
  --color-1: crimson;
  --color-2: blue;

  --bg: linear-gradient(to proper, var(--color-1), var(--color-2));
}

Now say there may be a few divs sitting on the web page:

<div></div>
<div class="variation"></div>

Lemme type them up:

div {
  background: var(--bg);
}

That completely works! Hell sure!

Now lemme type that variation. I don’t need it to go from crimson to blue, I would like it to go from inexperienced to blue. Simple tacky, I’ll replace crimson to inexperienced:

html {
  --color-1: crimson;
  --color-2: blue;

  --bg: linear-gradient(to proper, var(--color-1), var(--color-2));
}
div {
  background: var(--bg);
}
.variation {
  --color-1: inexperienced;
}

Nope! (Sirens blaring, horns honking, cattle taking cowl).

That doesn’t work, buddies.

The issue, as greatest I perceive it, is that --bg was by no means declared on both of the divs. It might probably use --bg, as a result of it was declared larger up, however by the point it’s getting used there, the worth of it’s locked. Simply since you change another property that --bg occurs to make use of on the time it was declared, it doesn’t imply that property goes out looking for locations it was used and updating all the things that’s used it as a dependency.

Ugh, that clarification doesn’t really feel fairly proper. But it surely’s the most effective I acquired.

The answer? Properly, there are a number of.

Resolution 1: Scope the variable to the place you’re utilizing it.

You possibly can do that:

html {
  --color-1: crimson;
  --color-2: blue;
}

div {
  --bg: linear-gradient(to proper, var(--color-1), var(--color-2));
  background: var(--bg);
}
.variant {
  --color-1: inexperienced;
}

Now that --bg is asserted on each divs, the change to the --color-1 dependency does work.

Resolution 2: Comma-separate the selector the place you set a lot of the variables.

Say you do the widespread factor the place you set a bunch of variables on the :root. Then you definitely run into this drawback. You possibly can simply add additional selectors to that principal declaration to be sure you hit the precise scope.

html,
div {
  --color-1: crimson;
  --color-2: blue;

  --bg: linear-gradient(to proper, var(--color-1), var(--color-2));
}
div {
  background: var(--bg);
}
.variation {
  --color-1: inexperienced;
}

In another maybe less-contrived instance, it’d look one thing like this:

:root, 
.button,
.whatever-it-is-a-bandaid {
  --padding-inline: 1rem;
  --padding-block: 1rem;
  --padding: var(--padding-block) var(--padding-inline);
}

.button {
  padding: var(--padding);
}
.button.less-wide {
  --padding-inline: 0.5rem;
}

Resolution 3: Blanket Mode

Screw it — put the variables in every single place.

* {
  --access: me;
  --whereever: you;
  --want: to;

  --hogwild: var(--access) var(--whereever);
}

This isn’t a great plan. I overheard a chat not too long ago wherein a medium-sized web site skilled a 500ms web page rendering delay as a result of each draw to the web page wanted to compute all of the properties. It “works” but it surely’s one of many uncommon instances the place you possibly can trigger legit efficiency issues with a selector.

Resolution 4: Introduce a brand new “default” property and fallback

All credit score right here to Stephen Shaw who’s exploration on all this is likely one of the locations I noticed this confusion within the first place.

Let’s return to our first demonstration of this drawback:

html {
  --color-1: crimson;
  --color-2: blue;

  --bg: linear-gradient(to proper, var(--color-1), var(--color-2));
}

What we need to do is give ourselves two issues:

  1. A method to override the complete background
  2. A method to overide a half of the gradient background

So we’re gonna do it this manner:

html {
  --color-1: crimson;
  --color-2: blue;
}
div {
  --bg-default: linear-gradient(to proper, var(--color-1), var(--color-2));
  background: var(--bg, var(--bg-default));
}

Discover that we haven’t declared --bg in any respect. It’s simply sitting there ready for a price, and if it ever will get one, that’s the worth that “wins.” However with out one, it’ll fall again to our --bg-default. Now…

  1. If I set --color-1 or --color-2, it replaces that a part of the gradient as anticipated (as long as I do it on a selector that touches one of many divs).
  2. Or, I can set --bg to reset the whole background to no matter I would like.

Seems like a pleasant method to deal with issues.


Typically there are precise bugs with CSS customized properties. This isn’t considered one of them. Despite the fact that it type of feels like a bug to me, apparently it’s not. Simply a kind of stuff you gotta learn about.

Supply hyperlink

Leave a Reply