CSS cascade: Importance
Tags: css, priority, style, cascade
Published: 2019-12-04 12:04:39

While preparing for Microsoft's [70-480 exam](https://www.microsoft.com/en-us/learning/exam-70-480.aspx) I came across a question in which I had to sort different stylesheets according to their origin and importance, and I got a bit confused.

Even though I'm using CSS for more than 10 years, I've never dig into the specs to find out more about the terminology. When I finally spotted the right place in the [specification](https://www.w3.org/TR/css-cascade-3/#cascading) it got more clear to me and I've decided to provide a simple illustration.

#Cascaded value

The cascading algorithm takes an unodrered list of declared values and outputs a single value that is called the **cascaded value**. The algoritm takes into account 3 factors:

1. **Importance**: The importance of each declaration
2. **Specificity**: The specificity of the css selectors
3. **Order**: The order of the css declarations in the source code

The following illustration presents the way that the cascade algorithm determines the final declaration (cascaded value).

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/k8863vpbqiqgeiv6cvvw.png)

Lets verify the above diagram with a real example:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/nh6bt3xh5xjwqo54cms9.png)

We are not going to cover all 3 steps of the cascading process, instead, we are going to explain only the first step, the **importance**.

Just to clarify some basic terms, consider the following rule:

```css
background-color: #ececec
```
The `background-color` string defines a CSS property and is called a **property declaration**.

The `#ececec` is the value given to the aforementioned property and is called the **declared value**.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/q7dzyfbwqccpms1nde0x.png)

Now, imagine that we have multiple CSS rules applied to the same element, declaring different values to the same property.

{% gist https://gist.github.com/kapantzak/633a2fa6a422b5946b363858c23bfeba file=style1.css %}

These rules may be at the same file, or may derive from different origins. The cascading algorithm has to choose one of those values to be the cascaded value.

#Origin

There are 3 main origins defined in CSS:
- **Author origin**: The rules written by a web developer (the author of the page)
- **User origin**: The final user of the browser may be able to alter the user agent's default styles
- **User agent origin**: The default styles applied by the browser

plus 2 additions from CSS extensions
- **Animation origin**: Rules created by CSS animations
- **Transition origin**: Rules created by CSS transitions

#Importance

- **Normal**: The default state of declarations
- **Important**: Any declaration with the `!important` annotation

#Order by origin and importance

Specification defines the following precedence for the above combinations in descending order (Top wins):

1. Transition declarations
2. Important user agent declarations
3. Important user declarations
4. Important author declarations
5. Animation declarations
6. Normal author declarations
7. Normal user declarations
8. Normal user agent declarations

Lets demonstarte the above hierarchy with some examples.

### Normal user agent declarations

We start with a simple HTML page with only one `p` element and no css declared, like this:

{% gist https://gist.github.com/kapantzak/633a2fa6a422b5946b363858c23bfeba file=index.html %}

In this case, what style is going to be applied to the document? The answer is the default user agent style. Opening the developers tools in Chrome (*Version 78.0.3904.108*) we see the following:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/p8nzwh7uupb1y6lh5k4k.jpg)

As soon as we do not provide any kind of style, the browser applies the default user agent style.

### Normal author over normal user agent declarations

Now, lets add a css file and add a rule for the `p` tag:

{% gist https://gist.github.com/kapantzak/633a2fa6a422b5946b363858c23bfeba file=author.css %}

After we reference the new css file inside out HTML, we reload the page and we inspect the `p` element:

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jyn8lk7v8qxinzjuei03.jpg)

Here we can verify the precedence of normal author declaration over user agent declaration.

### Animations over normal author declarations

What happens if we add an animation declaration?

{% gist https://gist.github.com/kapantzak/633a2fa6a422b5946b363858c23bfeba file=animations.css %}

According to the specification,

> The last declaration in document order wins [(see here)](https://www.w3.org/TR/css-cascade-3/#cascade-order)

So, we have intentionally placed the `color: green` declaration after the animation declaration, in order to verify that animations takes precedence over normal author declarations, regardless of their location inside the source code.

The following screenshot illustrates the fact that animation declarations take precedence over normal author declarations, even if the latter are placed after the former, inside the source code.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ajql21pp1r1dplwyha28.jpg)

### Important author over normal author declarations

According to the specification

> The importance of a declaration is based on whether or not it is declared `!important`

The following screenshot illustrates the precedence of an important author declaration (`color: blue !important`) over a normal one.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/4nsk7qn752wu7z51c9uf.jpg)

#Final thoughts

We have investigated the internals of the cascade algorithm and provided some simple examples trying to verify the expected behaviour.

We have, explicitly, verified the following facts:
- Precedence of normal author over normal user agent declarations
- Precedence of animations over normal author declarations
- Precedence of important author over normal author declarations

During the process of writing this post, I have tried to verify the predence of **normal author declaration over normal user declaration**, but I have failed to reproduce the expected behaviour, as shown in the following screenshot.

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/ccuewu7v9ji662p5fvwl.png)

Here, I tried to add some user style declarations (`color: blue;`) using the developer tools, but it seems that this rule takes precedence over the normal author declaration (`color: green;`).

For anyone interested, here is a [question](https://stackoverflow.com/questions/59153785/css-cascading-precedence-of-origin-and-importance) I've posted on Stack Overflow regarding this issue.

*Chrome version 78.0.3904.108 was used for the above examples*

#References

- [W3C - Value Processing](https://www.w3.org/TR/css-cascade-3/#value-stages)
- [W3C - Cascading](https://www.w3.org/TR/css-cascade-3/#cascading)
- [W3C - Transitions](https://www.w3.org/TR/css-transitions-1/)
- [W3C - Animations](https://www.w3.org/TR/css-animations-1/)
- [MDN - Cascade and inheritance](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance)
- [https://stackoverflow.com/questions/18252356/what-is-the-difference-between-default-user-and-author-style-sheets](https://stackoverflow.com/questions/18252356/what-is-the-difference-between-default-user-and-author-style-sheets)