3

I'm struggling to understand the following with CSS variables, I believe the code speaks for itself otherwise please let me know.

:root {
    --color: red;
    --hover-color: var(--color);
}

div {
    --color: green;

    background: var(--color);
}

div:hover {
    background: var(--hover-color);
}
<div>
Why am I red on hover? Shouldn't I be green? When inspecting this element on hover, chrome shows the green color!?
</div>

What's absolutely baffling to me is that when inspecting the element in Chrome Devtools it shows the hover color as green??

3
  • Do other browsers handle it differently? It's either a bug (within Chrome), or the variables are set by reference rather than by value. Commented Jun 23, 2020 at 17:35
  • Same behavior in Mac Firefox. Commented Jun 23, 2020 at 17:49
  • an important rule: never do evaluation at root level Commented Jun 23, 2020 at 20:02

2 Answers 2

5

--hover-color resolves to the --color value of the scope in which it exists, meaning it will compute the value detected at that time. This is to avoid dependency cycles. You can read about these cycles in the specification document.

Custom properties are left almost entirely unevaluated, except that they allow and evaluate the var() function in their value. This can create cyclic dependencies where a custom property uses a var() referring to itself, or two or more custom properties each attempt to refer to each other.

To prevent this, you would want to expand a bit, and do the following:

:root {
    --color: red;
    --hover-color: var(--color);
}

div {
    --color: green;
    --hover-color: var(--color); /* Added this here */

    background: var(--color);
}

div:hover {
    background: var(--hover-color);
}
<div>
I am green on hover, as expected.
</div>

But this raises an interesting issue with Chrome's DevTools, which indeed shows a green color preview next to the hover state's background value. You might want to file an issue and have this looked into.

Sign up to request clarification or add additional context in comments.

3 Comments

Oh I see. It's a little annoying we need to reset both --color and --hover-color, and really weird that Chrome shows it as green, but I can live with it. Thanks for the explanation.
I don't understand why you are refering to cycles here?
Now devtool can display the correct value. Looks like chrome has fixed this.
-1

What you are doing is , you are making a variable then passing color to it , purely my thinking don't know this is the reason or not

Let's say its a javascript variable , then

var color = red;
var hoverColor = multiplier * color;

Then , you passed

color  = green;

Then in hover , what happening is

hover = hoverColor; 

(i.e. hoverColor = someMultiplier * color & color is green)

1 Comment

CSS variables/properties are completely different to most other language's variables though. I understand why this would happen with JS.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.