Because the only way to override a stubborn style used to be writing a more specific one. Add a class, then two classes, then an id, then an exclamation mark. Cascade layers break that pattern. They let you decide which group of styles wins before specificity is ever considered.
If you do not write CSS yourself, this still matters to you. Specificity wars are why small visual changes on an old site take a day instead of ten minutes, and why a theme update sometimes wrecks a page nobody touched. It is a maintenance cost that shows up on invoices.
Cascade layers are one of the few CSS features that change how a codebase is organised rather than what a page can look like. That makes them easy to skip and unusually valuable once a project gets big.
They are named buckets for your styles, declared with the @layer at-rule. MDN describes @layer as a rule used to declare a cascade layer, which can also define the order of precedence when there are multiple layers. You put related rules in a layer, then say which layer beats which.
MDN documents three ways to create them. There is a named block, where you write @layer utilities followed by your rules in braces. There is a statement form, where a single line such as @layer theme, layout, utilities declares the order without any rules in it. And there is an anonymous layer, written with @layer and a block but no name.
The statement form is the one that changes how you work. Declaring the order at the top of your stylesheet, before any of the rules exist, means the priority of your whole system is written in one readable line rather than scattered through thousands of selectors.
They add a sorting step that runs before specificity. MDN puts it bluntly: once the layer order has been established, specificity and order of appearance are ignored. So a single class in a later layer beats a deeply nested selector in an earlier one, which is the opposite of what CSS taught everyone to expect.
The specification is explicit about the order things get compared in. The W3C CSS Cascading and Inheritance Level 5 document lists the sort steps as origin and importance, then context, then element-attached styles, then layers, then specificity, then order of appearance. Layers sit at step four and specificity at step five.
That one line of the spec is the whole feature. Specificity still exists and still resolves conflicts inside a layer. It just no longer decides fights between layers, which is where most of the painful conflicts in a large stylesheet actually happen.
For normal rules, later wins. The specification states that when comparing declarations belonging to different layers, for normal rules the declaration whose cascade layer is last wins. Put your utilities last and they override your components without needing a single extra class.
Above everything layered. MDN is direct about this: styles that are not defined in a layer always override styles declared in named and anonymous layers. The specification gives the same example, noting that unlayered declarations take precedence over explicitly layered ones even when the unlayered styles have lower specificity.
This surprises almost everyone the first time. The instinct is that unlayered CSS is the leftover pile and layers are the organised system, so layers should win. It works the other way round, and the reason is compatibility. Existing stylesheets have no layers, so they had to keep working as the highest-priority normal styles.
The practical consequence is a decision you make once. Either commit and put essentially all of your CSS into layers, or accept that any stray unlayered rule quietly outranks your careful ordering. A half-layered codebase is more confusing than one with no layers at all.
We use this deliberately in one place. A small set of genuinely final overrides can live outside any layer, where they win without needing !important. Used sparingly that is clean. Used casually it recreates the mess you were escaping.
The order flips. MDN explains that all important declarations within CSS layers take precedence over any important declarations declared outside of a layer, while all normal declarations within layers have lower priority than declarations outside a layer. The same reversal applies between layers.
So for important rules, MDN states that the order of precedence is the inverse of normal rules, which means the first declared layer wins rather than the last. If your order is theme, then layout, then utilities, an important rule in theme beats an important rule in utilities.
This sounds like a trap and is actually the sensible design. It means a base layer can set something that genuinely must not be overridden, and later layers cannot casually stomp on it with their own important flag. Importance becomes a considered escape hatch instead of an arms race.
Our advice has not changed though. If a layered system is working, you should rarely need !important at all. Reaching for it repeatedly is a sign the layer order is wrong, and fixing the order is the real repair.
Write one statement at the top of your main stylesheet listing every layer in priority order, lowest first. Nothing else in that line does any work, and it does not matter where the actual rules for each layer appear afterwards. The order is fixed by first mention, which is exactly what makes the pattern reliable.
That decoupling is the part worth appreciating. You can load your reset in one file, your components in twenty more, and your utilities last, in whatever build order suits you, and the priority stays as declared. File order stops being a source of bugs.
It also documents intent. A new developer reading that single line learns the architecture of the stylesheet in five seconds. Compare that to inferring priority by reading selectors and counting classes, which is how most legacy CSS has to be understood.
Yes. MDN gives @layer the Baseline Widely available status, noting that the feature is well established, works across many devices and browser versions, and has been available across browsers since March 2022. That is several years of support, which puts it well past the experimental stage.
The specification side is settled enough too. CSS Cascading and Inheritance Level 5 reached W3C Candidate Recommendation Snapshot status in January 2022, so the behaviour browsers implemented is the behaviour the spec describes rather than a moving target.
The one real caveat is that there is no graceful fallback. A browser that does not understand @layer ignores the block entirely, which means the styles inside it simply do not apply. That is a hard failure rather than a soft one, but at Baseline Widely available it is not a practical concern for most sites. Working out where a feature sits on that scale is a habit we described in our guide to knowing when a web feature is safe to use.
Five layers cover most sites. A reset layer first, then base element styles, then layout, then components, then utilities last. Anything third-party gets its own layer near the bottom, so vendor CSS can never outrank your own work no matter how it is written.
That third-party layer is often the single strongest reason to adopt the feature. Embedded widgets, booking tools, chat scripts, and analytics interfaces all ship CSS you do not control and cannot easily edit. Wrapping their stylesheet in a low-priority layer neutralises it without a single override.
Utilities go last on purpose. A utility class exists to win, and putting the utilities layer at the end means it does, without the specificity hacks that utility frameworks have historically needed. The class stays a single class and still beats everything before it.
How you name and split those layers should mirror the design system you already have. If your components are documented somewhere, the layer names should match that vocabulary rather than inventing a second one. We make the same argument about naming in our guide to building a design system for a website.
On a small site with one stylesheet and one author. If your CSS is under a few hundred lines and nobody has ever fought with specificity in it, layers add a concept without solving a problem you have. Complexity you do not need is still complexity.
They are also the wrong fix for scoping. Layers control which styles win, not which elements a style can reach. If your actual problem is that a component's CSS is leaking into places it should not, that is a scoping question, and the answer is better selectors or shadow DOM rather than a layer. They are equally the wrong fix for responsiveness, which is what CSS container queries are actually for.
Retrofitting a large live stylesheet is the third case for caution. Wrapping existing CSS in layers changes its priority relative to any unlayered rule, so a partial migration can produce visual changes in places you never touched. If you retrofit, do it in one pass with proper visual checking, not gradually.
Adding layers is also not a performance improvement. It changes organisation, not payload, and a badly structured stylesheet with layers is still a badly structured stylesheet. The feature buys maintainability and nothing else, which is a fair trade only when maintainability is what hurts.
On any new build with more than a handful of pages, yes. Declaring five layers at the top of your stylesheet costs one line and prevents a class of problems that gets more expensive every month. On an existing site, adopt them the next time you rebuild the CSS rather than as a standalone project.
The fastest way to see the benefit is with third-party CSS. Pick one embedded widget you have been overriding with !important, wrap its stylesheet in a low-priority layer, and delete the overrides. That is an afternoon of work and it usually makes the case on its own.
If you are dealing with a stylesheet nobody wants to touch and every change takes longer than it should, we are happy to look at it and say whether layers are the answer or whether something else is going on. Reach out at phoenix.studio.
Tell us where you want to go. We'll tell you how we'd get you there.