Introduction to Cascade Layers in CSS
Tags: css, cascadelayers, api
Published: 2022-11-17 21:23:11


Cascade layers is a new API that is currently being implemented into our browser. As of writing this, the [support is quite impressive](https://caniuse.com/css-cascade-layers) already.

Cascade layers allow encapsulation of our CSS rules that can be ordered by specificity. It offers cascade management without the hassle of specificity hacks and abuse of `!important`.

With CSS, one of the things I see people struggle the most with is writing selectors the right way. There are tons of ways to write a selector that will produce the same results, and it can be confusing.

When a selector isn’t working as intended, _what should we do?_

Should we “artificially” increase its specificity by adding selectors we don’t need?
Should we move it down our CSS file?
Should we reduce the colliding selector specificity?

BEM coupled with SCSS helps a lot to reduce these issues.
The principle is to namespace class names, so we can select anything using only one class selector. Everything has the same specificity.

A promising idea on paper, but it has its caveats on a large codebase spread around large teams.

Cascade layers allow us to encapsulate specificity of selectors to avoid collision in our style.

## How Does the Cascade Work?

To use cascade layers, we first need to understand how the cascade worked before its introduction.

The cascade is how the browser resolves conflicts between rules affecting the same element.

We can interact with it using the **selector specificity** and adding `!important` to our declarations.

### The Cascade Origin

Before Cascade layers, we already had Cascade layers of some sorts. We called them **cascade origins**.

There are 3 origins for CSS rules:

- **User agent styles** are the default styles from your browser, they define spacing, font sizes and set a lot of defaults
- **User styles** are provided by the user, but most browser will only let you choose a font size and family
- **Author styles** are the one we – the CSS developers – write for a living, and it has the highest specificity


![Different origins get different specificities](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e6lkyewri3bgjjc6cq31.png)

Different origins get different specificities

These origins encapsulate the specificity, exactly like Cascade layers do.
If you define a rule with a high specificity in the **user origin**, it can be overwritten with a lower specificity selector in the **author style**, because the author origin has a higher specificity than the user origin.

### The confusing way `!important` works

Since user styles have higher specificity than browser style, we’d expect an `!important` rule in user style will have higher specificity than an important rule in browser style, right?
Well, not exactly. Because when using `!important`, the cascade origin order is reversed.

Meaning the lowest specificity origin has the highest for rules using `!important`.

Cascade origins, from least specific to most:

1. Browser declarations
2. User declarations
3. Author declarations
4. `!important` Author styles
5. `!important` User styles
6. `!important` Browser styles


![Cascade origins order is reversed when using !important](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk5dlbptvrvzvbdiu8qj.png)

Cascade origins order is reversed when using `!important`

## Adding Cascade Layers in the Mix

Now that we studied how the cascade worked before the introduction of the Cascade layers API, let’s see what this new API brings to the table.

CSS Cascade layers provides a `@layer` rule we can use to define cascade layers.

These layers _contain_ the specificity of selectors, meaning a high specificity selector can easily be overwritten by a lower specificity selector in a higher specificity layer.
The `@layer` keyword wrap CSS selectors like media queries would do:

```css
@layer reset {
  .link {
    color: blue;
  }
}

@layer base {
  a {
    color: red;
  }
}
```

In this example, an `a` element with the `link` class will appear **red**, since the `base` layer has a higher specificity.

<aside>
⚠️ Note that non-layered selectors have higher specificity than any layered selector.

</aside>

The later a layer is defined, the higher its specificity, but we can declare their order up-front.

In this example, the reset layer has the lowest priority beside its rules living later in the code:

```css
@layer reset,base,utilities;

@layer base {
  ...;
}

@layer utilities {
  ...;
}

@layer reset {
  ...;
}
```

Also, we can encapsulate whole files into a layer using `@import`:

```css
@import url("reset.css") layer(reset);
```

### The usage of `!important`

Note that the usage of `!important` in layers works the same way that in the origins, meaning the `!important` rules in the lowest specificity layer have the higher specificity.

![In the author style, the `!important` is also reversed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r16fet3h4gwqspdq3qfl.png)

## Conclusion

I find this way of encapsulating CSS very useful. I can imagine using a date picker JS library that needs some CSS. By encapsulating that CSS into a layer and making it a higher priority than the base CSS, we ensure that none of our base styles will override that library CSS.

I strongly recommend you to pass [this short quiz on CSS Tricks](https://css-tricks.com/css-cascade-layers/#aa-test-your-knowledge-which-style-wins) to test your knowledge on cascade layers.

Sources:

- [CSS Cascading and Inheritance Level 5](https://drafts.csswg.org/css-cascade-5/#cascade-sort): the W3C draft for the feature
- [A Complete Guide to CSS Cascade Layers](https://css-tricks.com/css-cascade-layers/): A very complete and detailed guide on the matter, by [Miriam Suzanne](https://twitter.com/TerribleMia)
- [CSS Cascade Layers Explained](https://positivethinking.tech/insights/css-cascade-layers-explained/) by [Pierre H.](https://www.linkedin.com/in/pierre-henrion-08a59328/)
- [Hello, CSS Cascade Layers](https://ishadeed.com/article/cascade-layers/) by [Ahmad Shadeed](https://twitter.com/shadeed9)

**_I'm Tom Quinonero, I write about design systems and CSS, [Follow me on twitter](https://twitter.com/tomquinonero) for more tips and resources 🤙_**