• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/13/23

Understand how specificity affects your code structure

Now, you know why it's important to structure your code, but to do that effectively, you need to understand a key concept: specificity. 

What is specificity?

Let’s look at an example.  Say you have a button element with an  id  of submit-button  and a class of button:

HTML

<div id="submit-button" class="button">Click Here!</div>

And in your CSS file, you’ve assigned a different background color to each, as well as the button element:

 CSS

#submit-button {
    background-color: #15DEA5;
}

.button {
    background-color: #DB464B;
}

So, when you look at your button in a browser, what color will it be?

The answer lies in each of the selectors’ specificity. When an element has conflicting rules applied, such as multiple background colors, the browser will apply the rule from the most specific of the selectors.

But just how does a browser determine a selector’s specificity?

The four horsemen of specificity

The browser lumps CSS rules into four categories:

1) Inline styles:

<div style="background-color:#15DEA5;">Click Here!</div>

2) IDs:

<style> #submit-button { background-color: #15DEA5; } </style>

<div id="submit-button">Click Here!</div>

3) Classes, pseudo-classes, attributes:

<style> .button { background-color: #DB464B; } </style>

<div class="button">Click Here!</div>

4) Elements and pseudo-elements:

<style> div { background-color: #DB464B; } </style>

<div>Click Here!</div>

When the browser is deciding which of the conflicting rules to apply, it tallies up the number of categories being implemented by a selector. So our three selectors would be tallied as follows:

#submit-button {...} :

Inline

ID

Class

Element

0

1

00

.button {...}:

Inline

ID

Class

Element

00

1

0

div {...}:

Inline

ID

Class

Element

000

1

Once the tallying is done, the browser starts by looking at the scores in the left column, because inline selectors are the most specific. If there’s a selector with a higher score, the browser will apply its style. If there’s a tie, it moves right to the next column and does the same thing.

In the case of our three selectors, the first column is a tie, none have inline styles, so they all score a zero. So, the browser moves right to the ID column, where there is a clear winner: #submit-button  has a score of one, where the others have zero, so the browser will use its rule set for the background color.

Now what if you were to add a second class to the button selector?

HTML & CSS

<style>
.button.submit-button { background-color: #DB464B; }
</style>

<div class="button submit-button">Click Here!</div>

That would change its specificity to:

Inline

ID

Class

Element

00

2

0

Although it might seem like the new double class selector of  .button.submit-button would be more specific, it still loses out to #submit-button . Remember,  the browser works from left to right, and since#submit-button has a higher score in the ID column, the browser stops there. It doesn’t matter if a selector has two classes, or 200, an ID selector will always be more specific than a selector of classes.

But what if you really want to use the color from the class selector? Instead of a second class, you could add the  id  to it as well:

HTML & CSS

<style>
    #submit-button {background-color: #15DEA5;}
    #submit-button.button { background-color: #DB464B;}
</style>

<div id="submit-button" class="button">
Click Here!
</div>

Now you have:

#submit-button {...}   :

Inline

ID 

Class

Element

0

1

00

#submit-button.button {...}  :

Inline

ID

Class

Element

0

1

1

0

Now there is a tie for the ID column, so the browser moves right to the class column, where  .button wins 1-0, and the browser applies its background color to the button.

As you’ll see in the next chapter, you will often want to override certain attributes with a modifying selector, rather than writing out a ton of specific selectors. This helps make your code more modular and reusable.

As you’ve just seen, ID selectors are difficult and messy to override, and you want to write clean, maintainable code. By sticking primarily with class selectors, you help to ensure that they have lower specificity, making them cleaner and easier to override.

So, what happens if the browser goes through the columns and ends in a tie?

Battle royale: specificity with a tie

Change the #submit-button ID to a class,.submit and the CSS to match:  

HTML & CSS

<style>

.submit {background-color: #15DEA5;}

.button { background-color: #DB464B;}

</style>

 
<div class="button submit">

Click Here!

</div>

Both .submit and .button have the same score:

.button {...}  :

Inline

ID

Class

Element

00

1

0

.submit {...}  :

Inline

ID

Class

Element

00

1

0

So, which selector wins out?

In the case of a tie, the browser selects the last selector to have been declared, which is  .button :

.submit wins out over .button, as it was declared last
.submit wins out over .button, as it was declared last

So, if you swap them so that.button is declared last:

<style>
    .button { background-color: #DB464B;}
    .submit {background-color: #15DEA5;}
</style>

<div class="button submit">
    Click Here!
</div>

The browser will use .submit 's background color:

Now that .submit is declared last, its background-color is rendered
Now that .submit is declared last, its background color is rendered

By sticking with classes to create your CSS selectors, you ensure that they have a low but consistent specificity. This makes conflicting rules easier to predict and manage. In the next chapter, you’ll put your new specificity knowledge to use by creating modular structured selectors to style your site.

Try it out for yourself!

Ready to roll up your sleeves and code in this interactive exercise? We have a .btn class to style our buttons, which features a mint-green background color. As an alternative, we decide to make a class that will turn our button’s background pink, via the hex value #EA526F. But it doesn’t work! We’ve added it to our second button, but it’s still mint-green…

That means that the original .btn class must have a higher specificity than .btn-pink, right? We need to refactor our CSS so that we can override .btn’s background color when we apply .btn-pink.

  • Calculate the specificities of the button selectors in the CSS file.

  • Refactor the CSS so that .btn-pink overrides .btn’s background color and turns the second button pink.

This can be done by increasing the specificity of .btn-pink, but in the in interest of maintaining a minimal specificity throughout our code base, we would best be served reducing the specificity of .btn.

 When you're ready, check your work with this CodePen!

Let's recap!

  • There are four levels of specificity: 

    • Inline styles

    • IDs

    • Classes, pseudo-classes, attributes

    • Elements and pseudo-elements

  • Your browser applies the most specific elements first.

Example of certificate of achievement
Example of certificate of achievement