The point is that when I teach this, I tend to ask questions to help the learner to be more engaged and therefore more likely to remember the content, and because I look like a flippin’ loon if I talk about buckets for 10 minutes.
First question: Which is worth more, 1 grain of sand, or 2 grains of sand?
Answer: 2 grains of sand
Second question: If we go to the beach, and pick up a handful of sand. How much did we pay for that sand?
Answer: Nothing
“In this scenario, the sand is basically free, but 2 grains of sand will be worth more than 1 grain”
Third question: What could I use to carry a lot of sand?
Possible answers: Bucket, wheelbarrow, box, hands
Latch onto bucket or wheelbarrow if possible. If they say something weird like “hands”, guide them back to the answer you want. i.e. “Do construction workers use their hands to move sand around the construction site?”
Fourth question: What are buckets typically made out of?
Possible answers: Metal, plastic
At this point, we have established a few things that will be used to further build the analogy.
Fifth question: Ok, in terms of cost, which one is more expensive, a bucket made out of plastic, or a bucket made out of metal?
Answer: Metal
“Yeah, a metal bucket is always more expensive than a plastic bucket.”
Sixth question: What if we added 10 grains of sand to the plastic bucket? Would the total cost of sand and plastic bucket be more than the metal bucket with just one grain of sand in it?
Answer: No, the metal bucket with one grain of sand would still cost more.
Seventh question: “We have a plastic bucket, and a metal bucket. What kind of bucket could be more expensive than plastic or metal? Use your imagination – any answer is ok!”
Possible answers: Silver, gold, diamond, the Magna Carta curled into a cone shape, etc.
We need them to say something more expensive than metal.
So now, we have established a bunch of things, and we can start to piece it all together.
You now can reveal that the plastic bucket is HTML elements (type selectors, and pseudo-elements), grains of sand are deeper specificity. Same specificity is overwritten by the last instance
/* plastic bucket with one grain of sand */
div {
color: blue;
}
/* plastic bucket with one grain of sand */
div {
color: pink;
}
Result: <div>text</div>
would be pink
/* plastic bucket with two grains of sand */
div span {
color: blue;
}
/* plastic bucket with one grain of sand */
div {
color: pink;
}
Result: <div><span>text</span></div>
would be blue
However, the most common type of bucket — the bucket that will most likely be used for applying styles — is the one that represents classes (and attribute selectors, and pseudo-classes). It takes higher precedence than plastic because it is worth more. No amount of sand in the plastic bucket could make it worth more. No amount of precedence in only HTML elements could give it more precedence than classes.
div span {
color: blue;
}
.metal-bucket {
color: magenta;
}
Result:
displays magenta
If we mix HTML elements and classes, the higher precedence goes to whichever bucket has the most sand.
.metal-bucket .loses div {
color: white;
}
.metal-bucket .wins .because .more div {
color: red;
}
The gold bucket has higher precedence than the others.
#gold-bucket {
}
.metal-bucket .loses .despite .more .sand {
}
“So, that’s all you need to know! A quick and easy way to check computed styles is to press F12 to bring up your browser’s developer tools. If using FF; click the Inspector tab, or if using Chrome click the Elements tab, or if using IE install either FF or Chrome.
“However…”
“However…….”
“There are two more buckets. We don’t really want to use them because they can be dangerous. They are uranium and plutonium buckets. Do not touch them unless you know what you are doing.”
The “uranium” bucket would be inline styles. Ideally, these would not be coded into HTML because they overwrite the styles in the CSS files. We want to separate our styles and HTML to not only keep things clean, but to keep them behaving how we expect.
!important is the “plutonium” bucket. It’s dangerous and needs to be handled with care. If you are using !important, you have contaminated your project (that is a sweeping generalization, but try to drill that point home).
!important does have some use-cases such as in CSS frameworks for setting up core functionality like a .hide class, or within packages for making sure nothing can break it from the outside, but try to discourage both inline styles and !important as much as possible.
Well, there you go! The bucket analogy for demonstrating CSS specificity! For more details (and less buckets) please check out the MDN page on specificity!