CSS Specificity for Poker Players

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 attribute class="sidenote"
  • ID selectors such as #navigation matches the element with attribute id="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.

  1. Put generic declarations first (body, a) to define the overall styles for the page
  2. Override only those values necessary in the different sections with ID or class selectors (#navigation.a, .article)
  3. 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

1 13 Apr 2007

Excellent article! Love the analogy.

2 13 Apr 2007

I chuckled at this, brilliantly executed article :D great info also!

3 14 Apr 2007

A truely excellent description and so easy to read, even for a programmer like myself! ;o)

4 14 Apr 2007

Thanks Guys. I thought of this analogy a while back, and as I wrote it, all the cliches seemed to apply.

5 15 Apr 2007

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

6 26 Apr 2007

This article just opened up my scedule this evening. Saved me hours.

Thanks!

Nathan Sawyer
7 26 Apr 2007

Thanks Bramus and Nathan. It's nice to hear that folks are enjoying this and learning something too.