How are the points in CSS specificity calculated

Pekka's answer is practically correct, and probably the best way to think about the issue.

However, as many have already pointed out, the W3C CSS recommendation states that "Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity." So the geek in me just had to figure out just how large this base is.

It turns out that the "very large base" employed (at least by the 4 most commonly-used browsers*) to implement this standard algorithm is 256 or 28.

What this means is that a style specified with 0 ids and 256 class-names will over-ride a style specified with just 1 id. I tested this out with some fiddles:

  • 255 classes are not enough to override 1 id

  • ...but 256 classes are enough to override 1 id

  • ...and 256 tag-names are enough to override 1 class-name

  • ...but, alas 256 ids are not enough to override 1 inline style (Updated 2012/8/15 -- you'll have to use !important)

So there is, effectively, a "point system," but it's not base 10. It's base 256. Here's how it works:

(28)2 or 65536, times the number of ids in the selector

  • (28)1 or 256, times the number of class-names in the selector
  • (28)0 or 1, times the number of tag-names in the selector

This isn't very practical for back-of-the-envelop exercises to communicate the concept.
That's probably why articles on the topic have been using base 10.

***** [Opera uses 216 (see karlcow’s comment). Some other selector engines use infinity — effectively no points system (see Simon Sapin’s comment).]

Update, July 2014:
As Blazemonger pointed out earlier in the year, webkit browsers (Chrome, Safari) now appear to use a higher base than 256. Perhaps 216, like Opera? IE and Firefox still use 256.

Update, March 2021:
Firefox no longer uses 256 as a base.


Good question.

I can't tell for sure - all the articles I manage to find avoid the example of multiple classes, e.g. here - but I assume that when it comes to comparing the specifity between a class selector and an ID, the class gets calculated with a value of 15 only, no matter how detailed it is.

That matches my experience in how specificity behaves.

However, there must be some stacking of classes because

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o

is more specific than

.o

the only explanation I have is that the specificity of stacked classes is calculated only against each other but not against IDs.

Update: I half-way get it now. It is not a points system, and the information about classes weighing 15 points is incorrect. It is a 4-part numbering system very well explained here.

The starting point is 4 figures:

style  id   class element
0,     0,   0,    0

According to the W3C explanation on specificity, the specificty values for the abovementioned rules are:

#a            0,1,0,0    = 100
classes       0,0,15,0   = ... see the comments

this is a numbering system with a very large (undefined?) base.

My understanding is that because the base is very large, no number in column 4 can beat a number > 0 in column 3, the same for column 2, column 1 .... Is this correct?

I'd be interested whether somebody with a better grasp at Math than me could explain th numbering system and how to convert it to decimal when the individual elements are larger than 9.