Mark Caron

heyokadesign

for non compliant browsers


CSS 2.1 Selector Specificity

October 11, 2007

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.

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. The reason that it seems so many people feel the need to re-explain this topic is because not many people are willing to give themselves a headache reading what the W3C has to say 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. So, basically, selectors with a higher specificity will overrule other selectors in the cascading order.

How it works

The specificity is generally calculated using four numbers concatenated, like: a, b, c, d (W3C). I will explain further later on. And the other technique is to assign values to each type of selector and add them up. For instance, 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. For instance, 10 ID's in a style declaration will override an inline style, because 10 ID's are worth 100 x 10 which equals 1000 — inline styles being worth 1000. But this is not true, whatsoever. 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. The order of specificity is in that order. And, pseudo-elements are to be ignored.

Let's focus on b and c, since a and d are so simple. ID (b) selectors are the most valuable asset to CSS, so they are given the highest priority, next to inline styles. ID selectors are written with a # infront of the value given to the ID. So, #content is selecting <div id="content">. This has a value of 100. These selectors, like all selectors, can be used in combination with any others. With this, #main-area #content would add up to 200.

Class selectors and other attribute selectors are assigned the variable c. These are given a value of 10 each. Class selectors are denoted with a dot (.) before the name of the class, like .box. Attribute selectors of CSS 2.1 are supported by most modern browsers, and when I say modern browsers I mean not Internet Explorer 6. These are declared with the attribute inside a set of brackets — [ ]. The usual form is for it to be written following the element that has the attribute applied to it, but it is not necessary. Neither is the attribute value, if you'd like to style anything with a particular attribute in general. This form, in its common use, looks like a[rel="friend"]. The = can be replaced with ~=, *=, ^=, or $= depending on how you're equating the value. A better concept of these can be found on 456 Berea St's CSS 3 selectors explained post.

The part about the attribute selectors and their specificity that confused me, at first, was whether or not using class= or id= in the attribute selector made it behave like the # or . 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 (the .), regardless to whether it says id= within its little brackets. It will always have a value of 10. Thus, div[id="content"] is less 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 Addition" value
style="" 1, 0, 0, 0 1000
p 0, 0, 0, 1 1
p 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

Anyway, if you haven't seen any specificity charts before and this helped explain things further, then great! If you feel it was confusing or just plain wrong, please let me know. But, I do hope this helps — and check out the other explanations too, because Andy Clarke has an awesome one using siths from Star Wars. Maybe I'll make a diagram of my own someday.

Comments

Currently, there are no comments. Please leave one by filling out the comment form.

Comments Form

* Required Fields



Shout-Outs

More Information

heyokadesign is a personal website and showcase of works by Mark Caron. His portfolio is comprised of websites, artwork & paintings, photography, logo designs, and more. For more information about Mark Caron and this site, please start with About heyokadesign.

If you would like to contact Mark Caron he would love to read your comments, suggestions, critiques, and anything else you'd like to share.