a red-haired woman writes notes in a notepad while working at her desk

The Beginner’s Guide to CSS Specificity

Have you ever tried to override a CSS rule, only to find it not working as it should have? Or noticed when one element is targeted multiple times with different CSS selector combinations, only one rule is applied at a time? This is all because of CSS specificity rules.

CSS specificity rules can be one of the most confusing concepts to understand, especially for beginners.

If you are just starting out with CSS, as a standard order rule, you might think the latest CSS rule should override the old one. It seems simple, but it doesn’t always work out that way. It depends on CSS specificity, when and which CSS rule should apply.

So let’s break down what CSS specificity is and how to use it efficiently.

What is Specificity in CSS?

In simple words, if you have multiple CSS selectors for one element, the one with the higher specific value will be applied.

Different selectors have different weights and the browser will decide which one is the most relevant to that element.

How Does it Work?

The specificity of a selector can be categorized in the following four levels:

  1. Inline style or CSS
  2. IDs
  3. Classes, pseudo-classes, and attributes
  4. Elements or pseudo-elements

Inline styles or CSS, where CSS is applied directly on the HTML document, look like this <p style="margin-bottom: 0">. Inline styles will always have the highest specificity level.

Second in this order are IDs, like #content. So any selector using an ID will have the second highest specificity level.

Classes, pseudo-classes, and attributes are third in this order. They look like: .post, :hover, and [title], respectively.

Elements and pseudo-elements have the least value. li and :after are basic examples of an element and pseudo-element.

man coding at desk near bright blue wall

The Calculation

The specificity value can be calculated with the following guideline:

  • Inline style or css: 1,0,0,0
  • ID: 0,1,0,0
  • Class or pseudo-class and attribute: 0,0,1,0
  • Elements and pseudo-elements: 0,0,0,1
  • Universal selector(*): 0

To check your selector’s specificity level, you can use the Specificity calculator.

Basic Rules of CSS Specificity

Now that you have an idea of how specificity is organized, let’s discuss some general rules and examples!

This is the base HTML I’ll use in my examples. Here I have a small list within a container with #content.

[css]
&amp;amp;amp;lt;div id=&amp;amp;quot;content&amp;amp;quot;&amp;amp;amp;gt;

&amp;amp;amp;lt;ul class=&amp;amp;quot;list&amp;amp;quot;&amp;amp;amp;gt;

&amp;amp;amp;lt;li&amp;amp;amp;gt;Item 1&amp;amp;amp;lt;li&amp;amp;amp;gt;

&amp;amp;amp;lt;li&amp;amp;amp;gt;Item 2&amp;amp;amp;lt;/li&amp;amp;amp;gt;

&amp;amp;amp;lt;li&amp;amp;amp;gt;Item 3&amp;amp;amp;lt;/li&amp;amp;amp;gt;

&amp;amp;amp;lt;/ul&amp;amp;amp;gt;

&amp;amp;amp;lt;/div&amp;amp;amp;gt;

[/css]

Rule 1

If you have two or more of the same selectors for an element, they will all have the same specificity value, hence the lower one or the last one will be applied.

In the following CSS snippet, both selectors have equal specificity, so the li color will be yellow, since it’s placed further down the line.

[css]

ul li{

color: green;

}

ul li{

color: yellow;

}

[/css]
css containers color coded with numbers

Rule 2

If multiple selectors are used for one element, the selector with the higher specific value will be applied.

In the following example, li is targeted by two different selectors and both affect the font color. So, which rule should apply?

Like the previous instance, in CSS order concept the second one should apply (so the li color would be green) but because .list li has a higher specificity value than ul li, the color will remain red.

[css]

.list li{

color: red;

}

ul li{

color: green;

}
[/css]
css containers color coded with numbers

Rule 3

We saw class outweigh elements in specificity level, now let’s see what happens with an ID.

In the following example,  we have a class and ID both targeting the same element and affecting the font color. Again the same question: which rule should apply?

[css]

.list li{

color: red;

}

ul li{

color: green;

}
[/css]

As mentioned before, ID has higher specificity value than class, attributes, and elements, so the color will be blue. Always target ID for higher specificity level.

css containers color coded with numbers

Rule 4

!important will override any selector of any specificity value. But keep in mind that !important shouldn’t be overused, because it’s not considered a CSS best practice. 

If you are the author of your CSS and not overriding an existing rule, you would hardly need to use !important.

Use !important only when you are trying to override someone else’s CSS and your specificity is not able to outweigh the previous selector, especially when you can’t control the placing order of your CSS in the HTML.

This will happen mostly while working in WordPress, where you will find many CSS files already added by different plugins and themes.

Generally, plugin CSS is specific to the plugin and use IDs, inline-css, or even !important for higher specificity, to avoid any CSS conflict. To override that CSS, you have to use even higher specificity; for these scenarios you can use !important.

In the following example, I’m recreating the previous scenarios, with li targeted with different CSS selectors, but you can see that !important overrides all rules and the color will be yellow.

[css]

#content li{

color: blue;

}

.list li{

color: red;

}

ul li{

color: green;

}

ul li{

color: yellow !important;

}

[/css]

!important will give you the power to enforce your CSS above any specificity level. 

You need to be careful while using !important because you can’t override this rule. The only way to override an !important is to use another !important later in the CSS, so your CSS can easily look messy if you don’t understand the power of it.

A few exceptions

Elements and pseudo-elements have the least specificity, but there are a few interesting (and slightly confusing!) exceptions. (Confusing because they don’t seem to follow the rules we just saw.)

In this example, you’ll see  :first-child (pseudo-class) and :first-line (pseudo-element). We just learned that pseudo-classes will have higher specificity than pseudo-elements, so according to that, the paragraph’s first line color should be green, but instead it will be pink.

[css]

p:first-child{

color: green;

}

p::first-line{

color

:pink

;

}

[/css]

You may think the ordering would be an issue here, but even switching the order won’t change the output. The specificity calculator shows a different picture than the outcome.

css containers color coded with numbers

This is where specificity gets a bit confusing. I can only assume that the reason for this outcome is :first-line is closer to the element and probably treated as inline-style. You can check jsfiddle for another example.

How to use specificity efficiently?

If you understand the CSS specificity rules, you can use it very efficiently and make your CSS reusable.

Let’s say you want to use the same .button but with different background colors, so you set up a specific selector: .red-block .button.

[css]

.button{

background: #97bc2d;

font-size: 1em;

display: inline-block;

}

.button a{

display: block;

color: #fff;

padding: 1em 2em;

text-decoration: none;

}

.red-block .button{

background: red;

}

[/css]

If .button is wrapped in a .red-block container, then the default button background color will change to red.

CSS specificity is very useful when customizing WordPress themes, where you are trying to override the theme author’s CSS with your own.

Common mistakes to avoid

Some people use ultra-specific selectors, which is not a good practice. Be as specific as required only. For example, this code snippet targets the li but is too specific.

[css]

div#content ul.list li{

color: purple;

}

[/css]

If you are too specific with your CSS, it will become rigid and harder to re-use. You could easily write .list li instead of div#content ul.list li, which will make your CSS cleaner.

Additional resources

Conclusion

As you can see, CSS specificity is an important tool and every front-end developer should have it in their toolkit. A clear understanding of this concept can go a long way in making you a good front-end developer.

Get started

Build faster, protect your brand, and grow your business with a WordPress platform built to power remarkable online experiences.