State of the Browser

State of the browser is back for the 10th year! Join us in London or online on

Get tickets →

A Handy Use For Cascade Layers

I was just preparing a demo for an upcoming talk and it suddenly occurred to me that cascade layers would be a perfect solution to a problem I was having.

For any element of live coding, I like to meticulously prepare my demos to prevent any moments of friction on the day. I wanted to apply a bunch of default styles to a grid of cards in this container queries demo, but I wanted those styles to appear at the bottom of the stylesheet, so that when it came to live coding the demo I could write all the relevant code at the top, and the audience could just focus on the layout styles I would be discussing. However, there were a few styles that consequently wouldn’t be applied, as they would have been overridden by those further down. For example, at the top of the CSS file I want to apply a container query that would result in a horizontal card layout:

.grid__item-wrapper {
container: card / inline-size;
}

@container card (inline-size > 24em) {
.card {
flex-direction: row;
}

.card img {
width: 40%;
flex: 1 1 auto;
}
}

But further down in the stylesheet I was setting a flex direction of column on the card:

.card {
display: flex;
flex-direction: column;
}

Container queries themselves don’t increase specificity. I could write the following, and the body would always be blue:

@container layout (inline-size > 40em) {
body {
background: red;
}
}

body {
background: blue;
}

I could increase the specificity of the selector at the top of the file, but I didn’t like my chances of remembering to do that in the midst of a live coding session! Cascade Layers are a perfect solution. We can specify the order of layers at the top of the file:

@layer general, layout;

Then put our relevant styles inside them:

@layer layout {
/* Only the styles relevant to the demo go in this layer */
.grid__item-wrapper {
container: card / inline-size;
}

@container card (inline-size > 24em) {
.card {
flex-direction: row;
}

.card img {
width: 40%;
flex: 1 1 auto;
}
}
}

@layer general {
/* CSS reset and general styles not relevant to the demo go here */
}

This means the styles in the general layer will be applied first, despite being below those in the layout layer.

Container queries demo of a grid of cards in Codepen showing the order in which layers are applied in the CSS panel

Here’s the full demo:

See the Pen Container queries + cascade layers by Michelle Barker (@michellebarker) on CodePen.

Browser support

I was surprised by how widespread browser support already is for Cascade Layers — over 87% of browsers worldwide now support them. But, needless to say, an application that relies on Cascade Layers would not fare well in browsers that don’t support them. Happily there’s a PostCSS polyfill (which I haven’t tried out yet).

Caveats

The one drawback to using Cascade Layers here is that it seems to result in the container queries polyfill no longer working. It’s not a big deal for me in this instance as I’ll be using Chrome, but running the demo in Firefox means you won’t see the container queries in action. I’ve filed an issue.

Resources

Find out more about Cascade Layers but reading this comprehensive guide by Miriam Suzanne, or watch Bramus’s video from CSS Day.