How-To: CSS Specificity

Specificity determines which CSS rule will take precedence and be applied by browsers. Understanding the rules of specificity will allow you to target specific elements on the page and avoid situations where “the CSS just doesn’t seem to be working.”

Whenever two conflicting rules apply to the same element, the one with higher specificity will win.

The four levels of specificity from highest to lowest:

  1. Inline styles (attached directly to the element) E.g. <h1 style="color: #00f;">
  2. #IDs (a unique identifier for page elements)
  3. Classes (.class), attributes [attribute] and pseudo-classes such as :hover and :focus
  4. Elements such as <P> or H1 and pseudo-elements such as :before and :after

The most obvious case is where two rules are at different levels of specificity: the highest will always win, so:

When two CSS rules are at the same level, the specificity is governed by the number of elements/classes in the selector – more will give higher specificity.

If the specificity at one level is Equal, then the number of elements/classes in the lower levels will count – more will give higher specificity.

If the specificity is exactly Equal (the same level and the same number of elements/classes) then the last rule in the CSS sheet is the one that wins.

In extreme cases (> 255 classes/element tags) the browser can overflow a 32-bit integer value and assign the 'wrong' precedence to a rule. This is unlikely to happen in any real-world design.


p.styleA {font-family: sans-serif; }
.styleA {font-family: monospace; }

In this case a paragraph formatted as styleA will be styled as sans-serif, the second rule is over-ridden because an element + class has higher specificity than a class alone.

If we now add another CSS rule (and apply both styles to the <P>) the text will now become monospace, this time the first rule will be over-ridden because two classes have a higher specificity than one class + one element:

p.styleA {font-family: sans-serif; }
.styleA.styleB {font-family: monospace; }

If we now add a third rule we can switch the font to serif:

p.styleA {font-family: sans-serif; }
.styleA.styleB {font-family: monospace; }
.styleA.styleC {font-family: serif; }

However in this case the specificity is equal (two classes in each rule) so the order of the CSS rules becomes important (last one wins), if we swap them around the font will display as monospace:

p.styleA {font-family: sans-serif; }
.styleA.styleC {font-family: serif; }
.styleA.styleB {font-family: monospace; }

Three classes in a rule are more specific than two, so this will display the font as serif:

p.styleA {font-family: sans-serif; }
.styleA.styleB.styleC {font-family: serif; }
.styleA.styleB {font-family: monospace; }

Adding an extra class is almost always preferable to adding an ID. It leaves more options open.

As a general rule, don’t qualify ID rules with tag names or classes (use #btnID rather than button#btnID) and don’t qualify class rules with tag names (use .myclass rather than img.myclass)

“No problem can be solved until it is reduced to some simple form. The changing of a vague difficulty into a specific, concrete form is a very essential element in thinking” ~ John Pierpont Morgan


Class and ID - CSS selectors.
Inheritance - Cascading styles.
Attribute selectors - Target HTML elements based on a specific attribute.

Copyright © 2013-2022
Some rights reserved