Intro
You may have seen this tweet making the rounds recently:
If you haven't yet, I encourage you guess what you think the answer will be before continuing on (and even vote on the tweet if the poll is still open! - But please don't vote after this post. Working on the honor system here).
- Pink
- Blue
- Red
This is your final spoiler warning!
CSS Variables
If you're unfamiliar with CSS Variables, this code might look extra confusing to you. The TL;DR is that it allows you to assign a value to a variable, indicated by the --
and then reference that value across your CSS style sheet. This provides the benefit of not needing to update each instance of the code, but only update a single location.
/* Variables are often declared in the root pseudo-class
to ensure they are available across the entire style sheet */
:root {
--paddingVertical: 5px;
--paddingHorizontal: 10px;
--margin: 15px;
--textColor: black;
}
/* Referencing variables */
.example{
padding: var(--paddingVertical);
padding: var(--paddingHorizontal);
color: var(--textColor);
}
Codepen Example (Added border to the divs for emphasis):
For more details, check what MDN docs have to say.
The Solution
Now that we have CSS Variables out of the way (and are sufficiently below the fold), we can start looking at what's happening in the tweet's code (referred to as "the Quiz" from here on).
The Quiz's code:
So the answer to the question is red. But why?
What's happening in the Quiz is that the CSS Variable --myVar
is being overwritten and the last overwrite is the one that takes effect. You can see this in action by copying the span and adding it outside of the div with class='red'
:
Now we see that there is a red and blue "Hello World" being displayed. This is because the blue "Hello World" doesn't have the class which applies --myVar: red
and as such uses the most recent assignment that it can find (set on #blue
).
My Observations of the (current) results
As of the time of writing, the poll shows the following (1,454 votes):
- pink - 37%
- blue - 18%
- red - 45%
pink - I believe the uses of CSS variables is tripping people up and leading to the votes for pink. We're told over and over that CSS read's top to bottom, which could lead to believing that because --myVar: pink
is the closest to the bottom, that would mean pink is the value that myVar
is set to for the entire document.
blue - My initial explanation for the solution would be that it's a case of CSS Specificity (which after re-evaluating I'm not sure is the correct wording). I suspect that those choosing blue are either choosing what they perceive as the least likely answer because they think it is a trick question or evaluating that the id tag would take precedent over everything else (at least, that's what I used to think!)
You can read about CSS Specificity in these great posts by Emma and Muna:
Top comments (3)
I am super proud and impressed with myself for getting this right (even before the explainer!)
Thanks for this breakdown - I love when I can better understand concepts that I know, but don't really know... you know? ;)
Oh, I totally know! 😜
One of the tricks is that this isn't particularly practical, so even if you understand the concepts, seeing it in an abnormal way can throw you for a loop!
I admit it, I know nothing about CSS variables. I don't plan to until next year. Always wait a while until adopting things is my moto. I still haven't seen infinity war for that reason. No spoilers please, unless fake and filled with code references.