CSS Tutorial menu

CSS Cascade Layers (@layer)

Cascade layers let you put your CSS into ordered groups. A later layer always wins over an earlier one, no matter how specific the selectors are.

The Problem Layers Solve

In big projects, CSS comes from many places: a reset, a framework like Bootstrap, your own components, small helper classes. When they fight, you often end up writing longer selectors or adding !important just to win. That makes the CSS worse every month.

With layers, you decide the order of importance once, at the top of the file.

Creating Layers

Write @layer with the names, in order from weakest to strongest:

Example

css
@layer reset, base, components, utilities;

Then put rules into a layer with a block:

Example

css
@layer reset {
  * { margin: 0; box-sizing: border-box; }
}

@layer base {
  a { color: #264de4; }
}

@layer components {
  .btn { padding: 8px 16px; border-radius: 6px; }
}

@layer utilities {
  .hidden { display: none; }
}

The order comes from the first @layer line, not from where each block is written in the file.

Layers Beat Specificity

This is the key idea. Between two layers, the layer order decides, and specificity is only compared inside the same layer.

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
@layer base, components;

@layer components {
  .title {
    color: seagreen;
  }
}

@layer base {
  #page h1.title {
    color: crimson;
  }
}
</style>
</head>
<body id="page">

<h1 class="title">Workownix Tutorials</h1>

</body>
</html>
Try it Yourself »

The heading is green. #page h1.title is much more specific, but it is in the base layer, which comes before components.

The Cascade Order with Layers

For normal (not !important) styles, the browser checks in this order, from weakest to strongest:

StepSource
1Browser's default styles
2Your first layer
3Your later layers, in order
4Styles that are not in any layer
5Inline style="" attributes

So unlayered CSS beats all layered CSS. This is useful: if you put a framework in a layer, your own plain CSS beats it easily.

!important works the other way round with layers: an !important rule in an early layer beats one in a later layer. This lets a reset layer protect its most important rules.

Putting a Framework in a Layer

You can import a whole stylesheet straight into a layer:

Example

css
@import url("bootstrap.min.css") layer(framework);

@layer framework, custom;

@layer custom {
  .btn {
    border-radius: 999px;   /* beats Bootstrap's .btn rules */
  }
}

@import must be at the very top of the CSS file, before other rules.

Nested Layers and Anonymous Layers

Layers can contain layers. You refer to them with a dot:

Example

css
@layer components {
  @layer cards {
    .card { padding: 16px; }
  }
}

/* Add more to the same nested layer later */
@layer components.cards {
  .card h3 { margin-top: 0; }
}

A layer without a name (@layer { ... }) is anonymous. You cannot add to it later, so named layers are usually better.

A Complete Structure

Example

html
<!DOCTYPE html>
<html>
<head>
<style>
@layer reset, base, components, utilities;

@layer reset {
  * { margin: 0; padding: 0; box-sizing: border-box; }
}
@layer base {
  body { font-family: Arial, sans-serif; padding: 20px; }
  p { margin-bottom: 12px; }
}
@layer components {
  .alert {
    padding: 12px;
    border-radius: 6px;
    background-color: #fef3c7;
    color: #92400e;
  }
}
@layer utilities {
  .mb-0 { margin-bottom: 0; }
  .center { text-align: center; }
}
</style>
</head>
<body>

<p class="alert">Fee deadline: 25 October.</p>
<p class="alert mb-0 center">Results will be announced on Friday.</p>

</body>
</html>
Try it Yourself »

The small helper classes in utilities always win over components, so .mb-0 works without !important.

Exercise

Exercise

You declare @layer base, theme; A rule in base uses an id selector, and a rule in theme uses only a class. Which wins?

Learn CSS with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp