Some folks getting on board with CSS tend to get stuck on CSS specificity. The descriptions of which rules override other rules tend to make more sense to programmers than designers, since programmers are used to the concepts of inheritance and overriding properties.
If you're not from the programming world and CSS seems a bit confusing, perhaps this analogy may help clear some concepts up. Think of CSS rules as poker hands. The best hand determines an element's style.
Your Hand
Cards in this analogy would be the selectors within a CSS rule. Most CSS rules consist of element selectors, class selectors, and ID selectors.
- element selectors such as
div
- class selectors such as
.sidenote
matches elements with an attributeclass="sidenote"
- ID selectors such as
#navigation
matches the element with attributeid="navigation"
Ace High to Open
The weakest rules contain only element selectors.
h1 p { font-size: 1em; }
That rule is basically deuce high. Two element selectors, h1 and p. Pseudo-elements are considered elements for the purpose of specificity computation, so these two rules are equal in their specificity:
p:first-line a
div p a
However, we all know that a 5 beats a 3. In the same way, the most elements included in a rule will win the specificity hand. Five elements...
body div div h1 p
...beats three elements...
div h1 p
Tie-Breakers
If two rules have identical specificity as they do above, then the last rule processed wins. There's no direct poker analogy, but in blackjack, the dealer plays last and wins ties.
Pairs Beat Ace High
Even a pair of 2s beats a single Ace. In the same way, including a class selector beats any number of element selectors.
p.introduction
...or just...
.introduction
...beats...
html body div div h2 p
...as long as rules apply to the same p element. Also keep in mind that a class specification doesn't have to be associated with the final HTML element. This definition will also beat any element-only rule:
div.introduction p
Just the presence of the class specification anywhere within a CSS rule will give you a winning hand over any element-only declaration. And rules with more classes beat rules with fewer classes:
div.content div.summary p.intro
...beats...
div.content div p.intro
Pseudo-classes are considered classes for the purposes of computing specificity, making these two rules equal in their specificity...
div a:link
div a.friend
Three-of-a-Kind Beats any Pair
Just as any three-of-a-kind beats any pair, CSS rules with ID selectors beat rules with any number of class selectors.
#content img
...beats...
body div.wrapper div.summary p.intro img
And more ID selectors beat fewer ID selectors in the same way more class selectors beat fewer class selectors.
Full-House Beats Three-of-a-Kind
And, as you would expect, specifying an ID and a class will beat a rule with either one alone.
div#content.summary li
...beats all these...
div#content ul li
div.content div.secondary li
div ul li
The Joker is Wild
The ! important specifier is the Joker in the deck. The rules so far are easy and straightforward to follow. "! important" throws a wrench into the system.
In card-playing terms, the Joker trumps all. That means, your "! important" rules let you override otherwise more specific rules.
Use of this selector is discouraged because it disrupts the orderly cascade in play. Often folks add a rule to a style sheet and, when they don't see a change because of normal specificity rules, they slap "! important" to the rule. This is a misuse of the selector, sloppy CSS, and eventually leads to "! important" wars whereby every rule seems to need the selector. For instance:
#pagewrapper div a { color: black; }
...is (improperly) overridden by...
#content a { color: red ! important; }
...when just adding some specificity like this...
#pagewrapper #content a { color: red; }
...would have been a more appropriate way to apply styling to that area of the page.
Know When To Hold 'Em
The strategy I've adopted for styling documents doesn't give away my hand up front and gives me easy control over styling in all areas of the page.
- Put generic declarations first (body, a) to define the overall styles for the page
- Override only those values necessary in the different sections with ID or class selectors (#navigation.a, .article)
- Zero in on specific areas with additional ID or class selectors (#navigation ul.subsection a, #footer p a)
What you want to avoid is starting out by defining styles with high-value selectors, such as
div#pagewrapper div#contentwrapper a
Overriding the anchor styles later on would mean a lot of specification, so be strategic and start generically and build up specification values as you zoom in on specific elements on your page.
Know When To Fold 'Em
Take a look at these XHTML and CSS snippets. What color will the main paragraph text be?
XHTML:
<body>
<div id="pagewrapper">
<div class="content">
<p>This is the main paragraph.</p>
</div>
<div class="secondary">
<p>This is the secondary paragraph.</p>
</div>
</div>
</body>
CSS:
p { color: red; }
body div { color: brown; }
div#pagewrapper { color: blue; }
#pagewrapper div.content { color: green; }
The answer might surprise you. It will be red. Even though parent elements are specified to the gills and color is an inherited attribute, you must look for the element being styled first before taking into account any specificity conflicts.
In this case, all bets are off since the final three rules never targeted the paragraph element.
Other References
- specificity at westciv
- specificty for star wars fans
- specificity at snook.ca
- eric meyer on specificity
Comments
Excellent article! Love the analogy.
I chuckled at this, brilliantly executed article :D great info also!
A truely excellent description and so easy to read, even for a programmer like myself! ;o)
Thanks Guys. I thought of this analogy a while back, and as I wrote it, all the cliches seemed to apply.
Hilarious way to explain! Must say I'm more hooked to the CSS Specificity Wars though, as I know more about Star Wars than I know about Poker :-P
This article just opened up my scedule this evening. Saved me hours.
Thanks!
Thanks Bramus and Nathan. It's nice to hear that folks are enjoying this and learning something too.