Introduction to Cascade Layers

Table of contents

Cascade Layers is a way to organize your app’s styles by separating them into layers that stack on top of each other to give you more control.

Folios de colores apilados

They are independent but permeable layers, each with its own cascade and specificity logic. Since they stack, you can keep your code more structured, tidy, and easier to manage.

It’s like splitting your CSS into different style sheets and linking them one after another using <link> or <style>, but the behavior changes due to how specificity works in layers.

Actually, we already work with the concept of stacked styles. For example, user styles and developer (author) styles apply over the default styles that browsers give to HTML elements.

Captura del inspector de herramientas Captura del inspector de herramientas

But with Cascade Layers, you get much finer control by organizing styles by importance—more specific styles can take priority over more general ones.

What Problems They Solve

  1. Help organize styles into meaningful groups.
  2. Make it easier to override styles.

By splitting styles into layers, you can manage them better and deal more easily with overriding styles and specificity problems, especially in large projects.

What Problems Remain

  1. No native style encapsulation.

Layers are permeable—there’s no true encapsulation—so one can override another. If you’re not careful, this can lead to unexpected results. That’s why naming strategies like BEM are still useful.

Component-based style encapsulation is possible with tools like CSS Modules or CSS-in-JS, but they can lead to repeated class names across components. Since there’s still no native CSS encapsulation (except with web components), you need to be careful and follow a shared team methodology.

How to Use Layers

Creating Layers

Use the @layer rule to create a new style block. Layers can be named or anonymous.

/* Anonymous layer */
@layer {
	p {
		color: red;
	}

	@media (min-width: 457px) {
		a {
			color: pink;
		}
	}
}

/* Named layer */
@layer layout {
	.container {
		width: max(100%, 60rem);
	}
}

Layer Order

Order matters: the last layer wins and overrides the previous ones.

@layer default {
	.rectangle {
		background-color: coral;
	}
}

@layer theme {
	.rectangle {
		background-color: lime;
	}
}

Here, .rectangle will be lime.

You can control stacking order using @layer with a list of names, from least to most important.

@layer default, theme;

@layer theme {
	.rectangle {
		background-color: lime;
	}
}

@layer default {
	.rectangle {
		background-color: coral;
	}
}

.rectangle will still be lime because theme comes after default.

Merging Layers

You can repeat layer names—CSS will merge them into a single layer.

@layer theme {
	.rectangle {
		background-color: lime;
	}
}

@layer theme {
	.rectangle {
		background-color: coral;
		border: 1px solid;
	}
}

.rectangle will be coral with a border.

Nesting Layers

Layers can be nested for semantic grouping. You can refer to them later by name.

@layer theme {
	@layer base {
		.rectangle {
			padding: 1rem;
		}
	}
}

@layer theme.base {
	.rectangle {
		padding: 0 1rem;
		color: white;
	}
}

Importing External Files into Layers

You can wrap full CSS files in layers, for example third-party libraries, to let your own layers override them.

@import url(https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css)
layer(bootstrap);

@layer default, reset, bootstrap, components, theme;

Currently, you can’t wrap <link> imports in a layer, but there’s a proposal to make it possible.

<link rel="stylesheet" href="example.css" layer="<layer-name>" />
<link rel="stylesheet" href="example.css" layer />
<link
	rel="stylesheet"
	layer="bootstrap"
	media="supports(at-rule(@layer))"
	href="bootstrap.css"
/>

Layer Relation to Other Styles

The cascade takes all styles and sorts them based on priority.

According to W3C, the browser decides what styles to apply using this order:

  1. Source & importance (browser, user, author — with !important)
  2. Context
  3. Inline styles (style attribute)
  4. Layers
  5. Selector specificity
  6. Source order

Specificity in Layers

Within a layer, CSS specificity works the usual way. But across layers, a less specific selector in a later layer can override a more specific one in an earlier layer.

@layer theme {
	section#my-id.my-class {
		padding: 1rem;
		background: teal;
	}
}

@layer overrides {
	section {
		color: white;
		background: coral;
	}
}

Even though theme uses a more specific selector, overrides will win because it comes later.

Styles Outside Layers

Styles outside layers are treated as if they belong to a final, top-priority layer—even if they appear earlier.

section {
	background: aqua;
}

@layer theme {
	section#my-id.my-class {
		background: teal;
	}
}

@layer overrides {
	section {
		background: coral;
	}
}

The background will be aqua.

!important

A lower-priority layer with !important overrides later layers—even if they also use !important.

@layer defaults, theme, overrides;

@layer defaults {
	section {
		background: lime !important;
	}
}

section {
	background: aqua !important;
}

@layer theme {
	section#my-id.my-class {
		background: teal !important;
	}
}

@layer overrides {
	section {
		background: coral !important;
	}
}

The background will be lime.

Support

According to caniuse, browser support is nearly full—so you can use it safely.

Using in Real Projects

Cascade Layers can fit into any project, and you don’t need to go all in. They work well for:

@layer button, states;

@layer button {
	.button {
		padding: 1rem;
		border: 0;
		color: #282828;
		background-color: #36f5bf;
	}
}

@layer states {
	:hover {
		color: #fff;
		background-color: transparent;
	}

	:focus-visible {
		outline: max(2px, 0.08em) solid currentColor;
		outline-offset: 0.25rem;
	}
}

Conclusion

While it doesn’t give full encapsulation, Cascade Layers is a very helpful tool for managing styles.

Just keep in mind the layer priorities to avoid surprises. It may take a bit to get used to, but it gives you great control once you do.

comments powered by Disqus

If you find it interesting

If you have any doubt or you want to chat about this topic, as if you find interesting the content or our profiles and you think we could build something together, do not hesitate to contact us trough the email address hola@mamutlove.com