Computer scienceFrontendCSSSelectors in Depth

Specificity

5 minutes read

We know that CSS uses selectors to apply styles to the elements on a page. In different cases, a selector can designate many elements, or a small number of them, even a single one. And if it turns out that several selectors are used on one object at once, then how does CSS determine which rule to apply? This is what specificity is for.

The concept of specificity

Let's remember what types of selectors are there:

  • element selectors (like p);

  • class selectors (like .primary);

  • id selectors (like #yellow_block);

  • selectors made up of the ones listed above (like p.primary is made of p and .primary).

Also, we can use inline styles inside HTML like <p style="color: red;">Red text</p>.

The specificity of a selector is a four-digit number that is produced by counting tag names, classes, ids, and inline styles that are parts of the selector. In this topic, we will learn how it happens.

Ones (element selectors)

Let's take the following example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link href="styles.css" rel="stylesheet">
  </head>
  
  <body>
    <h2>Numbers</h2>
    <div>
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
    </div>
  </body>
</html>

To reduce code listings below we will repeat only <body>...</body>. Other parts of the code will stay unchanged, so there is no need to reread it.

Before styling, the output looks like this:

The list of numbers

Let's add the first style rule in styles.css:

h2 {
  width: 150px;
  background-color: #ffed63; /* yellow */
}

The result is the following:

The heading with the yellow background

Every single element name like h2 inside of a selector adds one point to one's place in a four-digit number of specificity. In our case when h2 is the whole selector name, we have 0001 as a specificity value. If there is a more complex selector like div > h2 (you will learn it later), the specificity would be 0002, because div and h2 are both element names, and so on.

Tens (classes selectors)

Now let's add some classes to HTML:

<!-- the previous code -->

<body>
  <h2 class="red">Numbers</h2>
  <div>
    <div class="item red">1</div>
    <div class="item blue">2</div>
    <div class="item green">3</div>
    <div class="item red">4</div>
    <div class="item green">5</div>
  </div>
</body>

<!-- the following code -->

And let's use these classes in styles.css:

h2 {
  width: 150px;
  background-color: #ffed63; /* yellow */
}

.red {
  background-color: #fc6156; /* red */
}

.blue {
  background-color: #2b62cf; /* blue */
}

.green {
  background-color: #74de66; /* green */
}

The result will be the following:

The heading with red background and the list with different colors

Every single class name in a selector adds one point to ten's place in its specificity. Notice that <h2>Numbers</h2> changed its background color from yellow to red. It happened because we added class="red" to <h2>, the rule with the .red selector has 0010 as a specificity value, and 0010 is more than 0001 (i.e. 10 > 1 just mathematically) of the h2 selector.

A rule with the highest specificity is the one that is applied.

Let's add one more CSS rule at the end of our stylesheet:

/* the previous rules */

.red.item {
  background-color: #ffed63; /* yellow */
}

After that the elements with red and item classes will become yellow:

The numbers list with yellow lines one and four

The specificity of .red.item composed from .red and .item is 0020, and 0020 is more than 0010 that a single .red has.

Hundreds (id selectors)

Now let's add an id to the third item:

<!-- the previous code -->

<body>
  <h2 class="red">Numbers</h2>
  <div>
    <div class="item red">1</div>
    <div class="item blue">2</div>
    <div class="item green" id="chosen">3</div>
    <div class="item red">4</div>
    <div class="item green">5</div>
  </div>
</body>

<!-- the following code -->

And let's use it in CSS:

/* the previous rules */

#chosen {
  background-color: #b257f7; /* purple */
}

The result will look like this:

The numbers list which have purple line on three

As you may have guessed, an id in a selector adds to its hundred's place. In this case, we have 0100 for #chosen. The previous rule applied to the third item was .green with a specificity of 0010, and 0100 is more than 0010 (100 > 10), so the third item became purple instead of green.

Thousands (inline style)

Finally, we have a thing that dominates over all previous ones: inline styles. Let's add the style attribute to the third item to make it orange:

<!-- the previous code -->

<body>
  <h2 class="red">Numbers</h2>
  <div>
    <div class="item red">1</div>
    <div class="item blue">2</div>
    <div style="background-color: #ffcb59;" class="item green" id="chosen">3</div>
    <div class="item red">4</div>
    <div class="item green">5</div>
  </div>
</body>

<!-- the following code -->

We don't need to change styles.css here, because the CSS rule for the third item has already been created by the inline style. So it did become orange:

The list of numbers different color which have one orange item on the third position

Inline style makes specificity with a value of 1000, and surely it's more than a value of any other combination of tag names, classes, and ids.

Conclusion

Let's summarize all the information above:

Selector

Specificity value

element (div)

0001

class (.changed)

0010

id (#point)

0100

inline style

1000

So, for example, the div > .emph selector has a specificity of 0011.
Let's move on to the tasks then!

33 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo