CSS Specificity And Why It Matters

Cover image

What is CSS Specificity

CSS specificity is the measurement of how strong a rule provided by a selector is, and determines which CSS rule is ultimately applied.

Why does it matter?

To be able to override an existing rule you need to know how to make your rule more specific (or better, equally as specific) then the rule that already exists. But making your CSS selectors more specific then then need to be, can lead to a constant fight to beat it. The use of BEM methology is an example of a way to greatly improve your management of your css's specificity by aiming to have just one level selectors.

How is it calculated?

A rules specificity is given a score (also refered to as its weight) that is calculated by breaking the rule into four catergories:

  • Inline Styles (n,0,0,0)

    • Any style that is inlined on the element
  • IDs (0,n,0,0)

    • The ID of an element #app
  • Classes / Attributes / Pseudo-Classes (0,0,n,0)

    • Any class names .red, attribute [type=text] or pseudo-classes :hover
  • Elements / Pseudo Elements (0,0,0,n)

    • Any elements div, or pseudo elements :after

The specificity is then calculated by counting how many are in each category, then concatenating the values in the order stated above, i.e

<style>
  #app div.amazing.red {
    color: red;
  }
  #app header div.amazing {
    color: green;
  }
</style>
<div id="app">
  <header>
    <div class="amazing red">Am i red or green?</div>
  </header>
</div>

In this example #app div.amazing.red has a score of 0121, calculated like so:

0 - Inline Styles
1 - ID
2 - Classes
1 - Element

Which wins over #app header div.amazing as it has a score of 0112, calculated like so:

0 - Inline Styles
1 - ID
1 - Class
2 - Elements

Other Rules

Rules with selectors of the same specificity

If a rule has selectors with the same specificity of an existing rule, the rule that came last is applied, this is the most ideal situation so you are not constantly increasing specificity with each rule.

!important is BAD

Batman teaching robin that important does not fix your bad css

A rule with !important wins over everything, even inline style. Awesome! you might think, then i don't have to worry about specificity, as your nice new rule will be applied. True... but then when it comes to override that rule, the only way to override that is to make another !important rule after the previous !important rule, and the terrible cycle begins.

  • Always look for a way to use specificity before even considering !important
  • Only use !important on page-specific CSS that overrides foreign CSS.
  • Never use !important when you're writing a component.
  • Never use !important on site-wide CSS.

Bottom line is you should never use !important unless you have to override an existing !important, but if you are never using !important in the first place you should never need to do this!

:not() exception

The :not() pseudo-class has no specificity value, but selectors placed into the :not() pseudo-class count as normal selectors when determining the count of selector types

Universal selector and combinators

Universal selector (*) and combinators (+, >, ~, '') have no specificity value.

Inheritance and User-Agent styles

Rules inherited from parent elements, and default user agent styles have no specificity score.

Bonus Image (Cheat-Sheet)

Front-End > 2018/02/08 > CSS Specificity And Why It Matters > css-specificity-wars.png