Your Complete Guide to CSS Specificity
Tags: webdev, css, programming, computerscience
Published: 2022-05-10 19:50:26

## Table Of Contents
* [Basics of Applying styles to HTML](#basics)
* [Priority of Styles](#css-priority)

* [What is Specificity](#specificity)
> [Calculating specificity](#spec-calc)
> [Specificity example](#spec-eg)

* [Conclusion](#conc)

## Basics of Applying styles to HTML<a name="basics"></a>
CSS is what gives your website its colors and design. There are 3 primary ways that we can apply styles to HTML. These are: 


- Inline Styles: Inline styles are exactly what the name implies, they are written inline with the HTML element. For example

```HTML
<div class="button-link" style="color: white; border: none; 
font-size: 16px; background-color: blue; width: 20%; 
padding: 1rem">Button Text</div>
```

This leads to the div to appear as given below, with the inline styles applied:
![Inline blue div](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hlh6ckj1v6zocmky8c1.png)

- Internal Styles: Internal style basically means that the styles to be applied are present inside the HTML document, but not inline. They are applied using a special HTML tag called `<style></style>`, that is written inside the `<head>` tag.
For example: 

```HTML
<!DOCTYPE html>
<html>
  <head>
    <title>CSS</title>
    <meta charset="UTF-8" />
    <style>
      .button-link {
        color: white;
        border: none;
        font-size: 20px;
        background-color: pink;
        width: 50%;
        padding: 1rem;
      }
    </style>
  </head>

  <body>
    <div class="button-link">Button Text</div>
  </body>
</html>
``` 

This code leads to the div looking like the following: 

![Internal pink div](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqjwvp10h2ibbzmr2ib8.png)

- External Styles: When a separate file is created that contains the styles to be applied to the whole document, and it is imported into the HTML code, this is called external style. External CSS can be imported into the HTML code using the link tag. For example: 

HTML file:

```HTML
<!DOCTYPE html>
<html>
  <head>
    <title>CSS</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="/src/styles.css" />
  </head>

  <body>
    <div class="button-link">Button Text</div>
  </body>
</html>
``` 
CSS file:
```CSS
body {
  font-family: sans-serif;
  font-size: 16px;
}

.button-link {
  color: yellow;
  border: none;
  font-size: 5rem;
  background-color: grey;
  width: 50%;
  padding: 1rem;
}
``` 
This code leads to the div looking like the following:

![External grey div](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jy6dhixw0jtc8xo7xql1.png)

<hr>
## Priority of Styles<a name="css-priority"></a>

Now let's try something, we'll try to apply all three together on that one div and see which one gets applied. It's extremely common for websites today to have multiple style sheets defined on one page.

HTML file:

```HTML
<!DOCTYPE html>
<html>
  <head>
    <title>CSS</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="src/styles.css" ; />
    <style>
      .button-link {
        color: white;
        border: none;
        font-size: 10rem;
        background-color: pink;
        width: 20%;
        padding: 1rem;
      }
    </style>
  </head>

  <body>
    <div
      class="button-link"
      style="
        color: white;
        border: none;
        font-size: 16px;
        background-color: blue;
        width: 20%;
        padding: 1rem;
      "
    >
      Button Text
    </div>
  </body>
</html>
``` 

CSS file:

```CSS
body {
  font-family: sans-serif;
  font-size: 16px;
}

.button-link {
  color: yellow;
  border: none;
  font-size: 5rem;
  background-color: grey;
  width: 50%;
  padding: 1rem;
}

``` 

The result is the same as the one we got for inline styles above:-
![Inline blue div](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hlh6ckj1v6zocmky8c1.png)

Why is this? It's because when different sources of styles are applied to one element, the source of the stylesheet matters in determining what style would finally be applied. In CSS, **inline styles have the highest priority, followed by internal and then the external styles**.

`Inline styles >  Internal styles > External styles`

This is demonstrated by the following video: 

![Priority of Styles gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cy5x042h36kid7bcynbt.gif)
<hr>
## What is Specificity <a name="specificity"></a>
Specificity comes into picture when the source of CSS styles is the same. In this case , there are two different conflicting CSS styles that point to the same element. 

So specificity helps to determine which style will get applied. It's like a ranking system for the different CSS styles. For example we have the below code:

```HTML
<!DOCTYPE html>
<html>
  <head>
    <title>CSS</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="src/styles.css" ; />
    <style>
     .button-link {
        color: white;
        border: none;
        font-size: 20px;
        background-color: purple;
        width: 20%;
        padding: 1rem;
      }
     div {
        color: black;
        background-color: yellow;
      }
    </style>
  </head>

  <body>
    <div class="button-link">
      Button Text
    </div>
  </body>
</html>
``` 

The div will have purple background and white font, even though a conflicting style is being applied as background=yellow and font=black. This is because of specificity.
<hr>
### Calculating specificity <a name="spec-calc"></a>
So how do we calculate it? As we need to compare it's very handy to have a numerical calculation for the priority of styles being applied to an element. To calculate specificity, let's consider a number of 4 digits:-
[0, 0, 0, 0]

Each position in the number represents the following:-

- Inline styles (1000s place) - Example: &lt;div style=&quot;color: blue;&quot;&gt;
- IDs (100s place) - Example: #footer
- Classes, pseudo-classes, attribute selectors (10s place) - Example: .button-link, :hover, [href]
- Elements and pseudo-elements (1s place) - Example: div, ::before

So in the above example, two different rules were defined, 

- one using .button-link class (Specificity = 0,0,1,0 = 10)
- second using div element (Specificity = 0,0,0,1 = 1)

Since the first specificity is higher, the first rule gets applied. Calculation rule can also be written as: 
> - _Start at 0, add 100 for each ID value, add 10 for each class, pseudo-class, attribute selector, and then add 1 for each element selector or pseudo-element._

Some calculation examples are given below:-
![Specificity calculation examples](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmy275fmb8hksue65rxt.png)

<hr>
### Specificity example <a name="spec-eg"></a>

Let's consider a simple example and try to guess which style will be applied to the div element in the below code:-
```HTML
<!DOCTYPE html>
<html>
  <head>
    <title>CSS</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="src/styles.css" ; />
    <style>
      /* Specificity = 0,1,0,0*/
      #btn {
        color: orange;
        background-color: blueviolet;
      }
      /* Specificity = 0,0,1,0*/
      .button-link {
        color: white;
        background-color: purple;
      }
      /* Specificity = 0,0,0,1*/
      div {
        color: black;
        background-color: yellow;
      }
    </style>
  </head>

  <body>
    <div
      class="button-link"
      id="btn"
      style="border: none; font-size: 20px; width: 20%; padding: 1rem;"
    >
      Button Text
    </div>
  </body>
</html>
``` 

As you might have guessed, the id selector has the highest specificity of 100 followed by class = 10 and then the element = 1. Thus the div looks as below:

![div spec example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qze7kdnag1ng5puljpfg.png)

What if we wanted to override the id style, would the below code work?

```HTML
<!DOCTYPE html>
<html>
  <head>
    <title>CSS</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" type="text/css" href="src/styles.css" ; />
    <style>
      #btn {
        color: orange;
        background-color: blueviolet;
      }
      .outer-box#outer .button-link {
        color: blue;
        background-color: green;
      }
      .button-link {
        color: white;
        background-color: purple;
      }
      div {
        color: black;
        background-color: yellow;
      }
    </style>
  </head>

  <body>
    <section
      class="outer-box"
      id="outer"
      style="background-color: grey; width: 60%; height: 10rem;"
    >
      <div
        class="button-link"
        id="btn"
        style="border: none; font-size: 20px; width: 20%; padding: 1rem;"
      >
        Button Text
      </div>
    </section>
  </body>
</html>
``` 

Yes! You can calculate the specificity and see that `.outer-box#outer .button-link` has a specificity of 1,2,0 or 120 which is greater than the previous id specificity being applied of 1,0,0 or 100. Thus the div now looks like this:- 
![div spec override example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7soyoiv1kz2vunxs0qki.png)

<hr>
## Conclusion and Important Notes<a name="conc"></a>


- Because of CSS's cascading nature, if two rules are applied to the same element, the one that comes last will be used.
- CSS Specificity is a very crucial topic to understand website styling and also for debugging the styles being applied to your site.
- This blog didn't touch upon it but `!important` is another useful concept to know. If a style declaration contains an important rule, it takes precedence over all other declarations. `!important` interacts directly with specificity, even though it has nothing to do with it. However, using `!important` is not recommended because it complicates debugging. Check [this](https://stackoverflow.com/questions/3706819/what-are-the-implications-of-using-important-in-css) for more information.

<hr>

> _That's all I have on this topic. Do let me know your thoughts and feedback below. Hope you learned something new through this!
Feel free to reach out to me on [Twitter](https://twitter.com/bhavzlearn) or [Linkedin](https://www.linkedin.com/in/bhavya-joshi-438178184/)_