We've Always Got Something to Say.

Read our thoughts on what's happening in the industry.

May 8 , 2009

CSS 2.1 Selector Specificity

by

I’m probably the 100th person to write about CSS 2.1′s selector specificity, but I’m going to take a stab at it anyway since it seems to be such a stumbling block for so many people.

Specificity Wars by Andy Clarke

Specificity Wars by Andy Clarke

I’m not writing this to take away from the brilliant explanations of Andy Clarke, Patrick Griffiths, Eric Meyer, or Molly E. Holzschlag, but to merely supplement their posts with, perhaps, another angle. Many people feel the need to re-explain this topic in layman’s terms rather than enduring W3C’s overly technical explanation about specificity.

What is specificity?

To be brief, it’s the applied calculation of the priorities of CSS selectors and how they cascade through a stylesheet. Simply put, selectors with a higher specificity will overrule other selectors in the cascading order.

How it works

There are two ways to determine specificity — the “right” way and the “quick and dirty” way. According to W3C, the specificity is officially calculated using four numbers concatenated, like: a, b, c, d . The “quick and dirty” technique is to assign values to each type of selector and add the values up. For example, general elements have a value of 1, classes have a value of 10, ID’s have a value of 100, and inline styles have a value of 1000. However, this value-based “quick addition” technique is a bit misleading because it presumes that 10 of any value will override the next highest selector. Following that logic if you have 10 ID’s in a style declaration those will override an inline style, because 10 ID’s are worth 100 x 10 which equals 1000 — inline styles being worth 1000. This statement is far from true. However, it can still be used as an easy way to get an idea of the specificity of a particular selector in a declaration; but it should never be fully relied upon.

The W3C states that Concatenating the four numbers a-b-c-d (in a number system with a large base) gives the specificity. This is the correct method to rely on. The reason is because it separates the values into 4 categories: a, b, c, & d. The variable a is reserved for the number of inline styles and has the highest priority. While b is for the number of ID’s, c is for the number of other attributes (including class, but not ID’s) and pseudo-classes, and d is the number of elements. This is the correct order of specificity and pseudo-elements are to be ignored.

Let’s focus on b and c since these are the subjects of confusion. ID selectors (b) are the most valuable asset to CSS, so they are given the second highest priority, next to inline styles (a). ID selectors are written with a # in front of the name given to the ID. So, #content is referencing <div id="content"> which has a value of 100 using the “quick and dirty” method. These selectors, like all selectors, can be used in combination with any other selectors. For instance, #main-area #content would add up to 200.

Class selectors and other attribute selectors are assigned the variable c. These are each given a value of 10 using the “quick and dirty” method. Class selectors are denoted with a dot (.) before the name of the class, like .box. Attribute selectors are declared with the attribute name inside a set of brackets — a[rel="friend"]. It is not necessary to include the value of the attribute. Additionally, the = can be replaced with ~=, *=, ^=, or $= depending on how you’re equating the value. A better concept of these equations can be found on 456 Berea St’s CSS 3 selectors explained post.

Note: Attribute selectors of CSS 2.1 are supported by most modern browsers, and when I say modern browsers I do not mean Internet Explorer 6.

Initially what confused me about attribute selectors and their specificity was whether or not using class= or id= in the attribute selector made it behave like the # (ID) or . (class) of its CSS 2 predecessors. After doing some testing and reading, I found that the attribute selector has the exact same specificity as the class selector (.), regardless of whether it says id= within its little brackets. It will always have a value of 10. Thus, div[id="content"] is less specific than div#content.

Here’s an easy way to visualize all of this (in a poorly misunderstood table element):

example inline style ID selectors class/attribute selectors element/type selectors “quick and dirty” value
style="" 1, 0, 0, 0 1000
p 0, 0, 0, 1 1
p em
0, 0, 0, 2 2
p.whatever 0, 0, 1, 1 11
p[id="whatever"] 0, 0, 1, 1 11
p[href="whatever"] 0, 0, 1, 1 11
#whatever p 0, 1, 0, 1 101
#whatever p.whatever 0, 1, 1, 1 111
#whatever1 #whatever2 p.whatever 0, 2, 1, 1 211

If you haven’t seen any specificity charts before I hope my interpretation helped explain it further. Be sure to check out the other explanations too, because Andy Clarke has an awesome example using siths from Star Wars. Maybe I’ll make a diagram of my own someday.

Mark Caron

About the Author

Around Atlantic BT, Mark is known as the company standards & web standards enforcer as well as the CSS guru. But technically, he's just the Senior Designer. Several years ago Mark helped push our company in a better direction with project development guidelines for following web standards, semantic markup, accessibility and CSS based layouts. And since these things seem to be what he's most passionate about, he fits nicely in that role.

2 Responses to “CSS 2.1 Selector Specificity”

  1. HaugReeneuh says:

    Your blog is so interesting! I have subscribed on rss and I will read it regullary/

  2. Awesome blog! Subscribed on rss. Regular will read it. Good job.

Leave a Reply

 

In a Nutshell

Since 1998, Atlantic BT has been a full service web development company that offers the tools, resources and services to get your business moving. We focus on combining new ideas, specific requirements, and years of experience into high-quality, results-oriented web solutions for small to medium sized businesses. If you want the best website possible that generates real results, let's get started.

Atlantic Business Technologies, Inc.
4509 Creedmoor Road, 3rd Floor
Raleigh, North Carolina 27612
  • Pinnacle Business Award Winner
  • Triangle Business Journal's Top 40 Under 40
  • Yahoo Search Marketing Ambassador
  • Google Adwords Qualified Company