Some people are confused by CSS Specificity, especially with all of the (not-so) new CSS3 Selectors. The image below may help make sense of CSS Specificity. Download the PDF

Legend:

X-0-0: The number of ID selectors, represented by Sharks

0-Y-0: The number of class selectors, attributes selectors, and pseudo-classes, represented by Fish

0-0-Z: The number of type selectors and pseudo-elements, represented by Plankton a la Spongebob

*: The universal selector has no value

+, >, ~: combinators, although they allow for more specific targeting of elements, they do not increase specificity values

:not(x): The negation selector has no value, but the argument passed increases specificity

You can download the PDF of fishy CSS specificity here

Specificity determines which CSS property declaration is applied when two or more declarations apply to the same element with competing property declarations. The most specific selector takes precedence. If specificity is equal, the last declaration in the source order takes precendence.By understanding CSS Specificity, you’ll understand how the browser determines which declaration is more specific and will therefore take precedence. Let’s take this paragraph as an example:

<p class="myClass" id="myDiv">

If you’re familiar with CSS, you’re probably very familiar with the CSS and specificity of these three lines:

#myDiv { color: red;} 1-0-0 .myClass {color: blue;} 0-1-0 p {color: yellow;} 0-0-1

The style block contains three style rules that have a selector that matches the paragraph. If cascade, or source order, were the only concern, the paragraph would be yellow. However, different selectors have different weights. An ID takes precendence over a class selector takes precendence over a type selector. So, the paragraph would be red.

With CSS3 Selectors, order is even more important, as is understanding specificity:

p.myClass { color: red;} 0-1-1 p[id^='my'] {color: blue;} 0-1-1 p:nth-of-type(1n) {color: yellow;} 0-1-1

Had we declared the above three lines instead, source order would be relevant, as class selectors, attribute selectors and structural pseudo-classes all have the same weight in terms of the cascade.

Selector Specificity Weights

!important: Any property declaration with the term !important takes highest precendence, even over inline styles. If !important is declared more than once on conflicting properties targeting the same element, you CSS author be shot, and the other precendence rules are in effect. It’s as if the weight of the selector with the !important declaration were 1-X-A-B-C, for that property only (where A, B and C are the actual values of the parent selector as described below). Because of this, important should not be used, but can be handy in debugging. style=””: If the author includes style attribute on an element, the inline style will take precedence over any styles declared in an external or embedded stylesheet, other than !important declarations. Anyone including style in production should also be shot, Just sayin’. Note that styles added with the JavaScript style (i.e. document.getElementById('myID').style.color = 'purple'; ) property is in effect creating an inline style ( ... id="myID" style="color: purple"... ). The weight of style=”” is 1-0-0-0. id: Among the selectors you’ll actually be including in your stylesheet, ID’s have the highest specificity. The weight of an id selector is 1-0-0 per id. class/pseudo-class/attributes: As shown in the second code block above, class selectors, attribute selectors and pseudo-classes all have the same weight of 0-1-0. type: Element type selectors and pseudo-elements, like :first-letter or :after have the lowest value in terms of specificity with 0-0-1 per element.

If more than one selector have the same specificity, then adhere to the cascade: the last declared rule takes precedence.

Calculating Specificity

To calculate the specificity of a declaration, count the element types, class/pseudo-class/attributes and ids in your declaration. Add each group up separately.

Using the expression X-Y-Z

To calculate X, count the number of ID attributes in the selector.

To calculate Y, count the number of classes, attributes selectors and pseudo-classes in the selector. Do not count :not, but do count the selectors passed as an argument in the :not(X-Y-Z) selector.

To calculate Z, count the number of element names and pseudo-elements in the selector.

For example, if you have 1 id, 12 class/pseudo-class/attributes, and 5 types, you are over declaring your selectors, but the value would be 1-12-5. Note that the final value of X-Y-Z is not a number, but a matrix. No matter how many class, attribute and pseudoclass selectors you have, a single ID will overpower them. If you use the speciFISHity example, no quantity of plankton (elements) will ever beat out a fish (class). No fish will beat out a shark (id). Not Shark can win against an oil tanker (inline), and even an oil tanker will succumb to a nuclear blast. Yeah, I got political on you!

Things that are less obvious: