Cascade Layers

Avatar of Chris Coyier
Chris Coyier on (Updated on )

DigitalOcean joining forces with CSS-Tricks! Special welcome offer: get $100 of free credit.

There is a new thing coming in CSS: @layer.

This comes from Miriam Suzanne, who is really on a tear with influencing important new CSS stuff. I’ve been hearing about all this, but then all a sudden it just dropped in experimental browsers.

Leave it to Bramus to really dig into all this with a fantastic post on it all:

With Cascade Layers coming, we developers will have more tools available to control the Cascade. The true power of Cascade Layers comes from its unique position in the Cascade: before Selector Specificity and Order Of Appearance. Because of that we don’t need to worry about the Selector Specificity of the CSS that is used in other Layers, nor about the order in which we load CSS into these Layers — something that will come in very handy for larger teams or when loading in third-party CSS.

Bramus Van Damme, “The Future of CSS: Cascade Layers (CSS @layer)

Emphasis mine.

That’s the rub here: this is a new thing that affects which selectors win. It’s going to require some re-wiring of our CSS brains, because layers is this entirely new (and powerful) part of determining what styles actually get applied.

I say powerful because a “higher” layer can literally beat a traditionally stronger selector even with a weaker selector in the layer.

/* First layer */
@layer base-layer {
  body#foo {
    background: tan;
  }
}
/* Higher layer, so this wins, despite selector strength */
@layer theme-layer {
  body.foo {
    background: #eee;
  }
}

/* Careful! Unlayered styles are more powerful than layers, even if the selector is weaker */
body {
  background: red;
}

Because that CSS at the bottom isn’t in a layer at all, it wins, even with the weaker selector

And you aren’t limited to one layer. You get to define them and use them however you want.

@layer reset;     /* Create 1st layer named “reset” */
@layer base;      /* Create 2nd layer named “base” */
@layer theme;     /* Create 3rd layer named “theme” */
@layer utilities; /* Create 4th layer named “utilities” */
/* Or, @layer reset, base, theme, utilities; */


@layer reset { /* Append to layer named “reset” */
  /* ... */
}

@layer theme { /* Append to layer named “theme” */
  /* ... */
}

@layer base { /* Append to layer named “base” */
  /* ... */
}

@layer theme { /* Append to layer named “theme” */
  /* ... */
}

Mind-blowing, really.

How are we going to use this?

I wonder if a common pattern might turn into…

  1. Layer everything, so priority levels are really clear. Maybe allow unlayered CSS for super powerful overrides only, but ideally even do that as a high-level layer.
  2. Resets as the lowest layer.
  3. Third-party stuff as the middle layer(s).
  4. Anything team-authored as the highest layer.

You won’t have to worry about leaving space in between (like you might with z-index) because you can adjust it without needing to attach numbers at any time.

Time shall tell.

Debugging

I hope DevTools expresses layers really clearly because there is going to be some serious head-scratching for a while when we see weaker-looking selectors winning because of layer placement.

Browser Support

Looks like caniuse is on the ball here!

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

Desktop

ChromeFirefoxIEEdgeSafari
9997No9915.4

Mobile / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
10310110315.4

Updates

This stuff is super new (at the time of writing), so volatility is to be expected, I suppose. Looks like on October 6th, 2021 it was decided that unlayered styles are actually the strongest styles, not the weakest. I’ve attempted to update the article to show that.