Navigation

Syntax

Cascade layers

Generated layer selection, native rule ownership, importance and rule ordering.

On this page

Master CSS emits generated style rules into utilities unless a class explicitly selects another supported layer. Managed theme declarations use theme. Native CSS keeps its authored layer, including native rules that expand a mixin with @apply.

This page defines layer ownership and generated rule ordering. For a component override and a DevTools diagnosis workflow, see Cascade layers in Guide.

Establishing the order

The base stylesheet, exposed as @master/css/base.css and included by the full @master/css import, declares:

@layer theme, base, defaults, components, utilities;

Load it before other rules establish these layers. CSS determines layer order by first appearance; a later order statement cannot rearrange layers already established. Generated layer blocks do not insert this statement themselves.

Normal and important declarations

For competing normal declarations in these layers, utilities has the highest priority and theme the lowest. Normal unlayered author rules take precedence over all of them. !important reverses the order between layers and places important layered rules above important unlayered rules. This comparison is within author stylesheets; it is not the complete cascade across origins, inline styles, animations or transitions. See CSS layer ordering.

Importance reverses layer precedence

Compare declarations of the same importance within author stylesheets. Normal unlayered rules outrank named layers; important named layers outrank important unlayered rules.

Text description
  1. The base stylesheet declares theme, base, defaults, components and utilities in that order.
  2. For normal author stylesheet declarations, priority increases from theme toward utilities, with unlayered declarations above every named layer.
  3. For important author stylesheet declarations, priority increases in the opposite direction: theme is strongest among these layers, and unlayered important declarations are weakest.
  4. Layer precedence is compared before selector specificity. The diagram compares each importance group separately, not normal declarations against important declarations or other cascade origins.

Layer precedence is considered before selector specificity. A more specific component selector therefore cannot defeat a normal utility declaration merely through specificity. Between declarations in the same layer, the remaining cascade criteria still matter; see selector specificity.

Layer ownership

LayerGenerated contentNative CSS convention
themeRetained managed token declarations under :root, :hostToken defaults
baseClasses with @layer(base)Normalization and document baselines
defaultsClasses with @layer(defaults)Broad project or content defaults
componentsClasses with @layer(components)Reusable product classes
utilitiesOrdinary utilities, recipes and native declaration classes; explicit @layer(utilities)Local utility rules

The native CSS column describes intended responsibilities, not a restriction on which properties CSS permits in a layer. defaults is a project layer, not the browser's user-agent stylesheet. Token dependency delivery is covered by Variables and modes.

Selecting a generated layer

The class suffix accepts exactly four layer names:

@layer(base)@layer(defaults)@layer(components)@layer(utilities)

It selects the layer for the entire generated class. It does not create a sublayer or move the theme variables that class depends on. Place it with the other suffixes, before a trailing !.

FormResult
block@layer(defaults)The display rule goes into defaults
block@layer(base)@layer(base)One base-layer rule; repeating the same choice is allowed
block@layer(base)@layer(utilities)CLASS_SYNTAX_ERROR: a class cannot select different layers
block@layer(theme)UNKNOWN_CONDITION: theme is not a generated style-layer target
block@layer(custom)UNKNOWN_CONDITION: arbitrary native layer names are not class suffix targets

Use native @layer syntax for project-specific layers and sublayers. Their order follows native CSS; the class suffix does not register new layer names.

Selecting a style layer does not move its token

The two layer bands show output ownership. Their positions are not a complete cascade comparison.

Text description
  1. p-md@layer(defaults) emits the generated padding declaration in the defaults layer.
  2. Its --spacing-md dependency still emits under :root,:host in the theme layer. @layer(defaults) selects the class rule’s layer, not its dependency’s layer.

Base and defaults

A base-layer descendant rule can establish a structural baseline:

<body class="(list-style:none)_ul@layer(base)">…</body>
Generated CSS
@layer base {  .\(list-style\:none\)_ul\@layer\(base\) ul {    list-style: none  }}

A defaults-layer descendant rule can establish code typography while leaving local component and utility decisions stronger:

<body class="font-mono_:is(code,pre)@layer(defaults)">…</body>
Generated CSS
@layer theme {  :root,  :host {    --font-family-mono: var(--font-mono, ui-monospace), SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace  }}@layer defaults {  .font-mono_\:is\(code\,pre\)\@layer\(defaults\) :is(code, pre) {    font-family: var(--font-family-mono)  }}

The font-mono class stays in defaults; its required font token remains in theme. The selector suffix determines the descendants that receive the declaration, independently of the layer choice.

Defaults stay below local decisions

Here both rules target the first paragraph. Its own native declaration class goes into utilities, so it overrides the article's defaults-layer font size:

<article class="(font-size:1rem)_p@layer(defaults)">  <p class="(font-size:1.5rem)">24</p>  <p>16</p></article>
Generated CSS
@layer defaults {  .\(font-size\:1rem\)_p\@layer\(defaults\) p {    font-size: 1rem  }}@layer utilities {  .\(font-size\:1\.5rem\) {    font-size: 1.5rem  }}

Native rules and managed utilities

A native class inside @layer components remains native CSS. It is delivered by default and follows native source order within that layer; it does not gain Master selector or condition suffixes. @prune native controls whether unused native selectors may be removed.

In this example .btn declares inline-flex, while flex generates a normal utility declaration. With the base order established, the button uses display: flex:

@layer components {  .btn {    display: inline-flex;  }}
<button type="button" class="btn flex">Save</button>
Generated CSS
@layer components {  .btn {    display: inline-flex;  }}@layer utilities {  .flex {    display: flex  }}

An on-demand @utility instead registers a managed class. Its ordinary output belongs to utilities, but a suffix can select another supported layer:

@utility flow {  display: grid;  gap: var(--spacing-md);}
<div class="flow@layer(defaults)">Example</div>
Generated CSS
@layer theme {  :root,  :host {    --spacing-md: 1rem  }}@layer defaults {  .flow\@layer\(defaults\) {    display: grid;    gap: var(--spacing-md)  }}

For utility definitions and native preservation, see Utilities and mixins.

Mixin expansion keeps the surrounding layer

An @apply inside a native rule expands declarations where it appears. It does not move that rule into utilities:

@mixin --inset {  padding: 1.5rem;}@layer components {  .card {    @apply --inset;  }}
<div class="card p(8)">Example</div>
Generated CSS
@layer components {  .card {    padding: 1.5rem  }}@layer utilities {  .p\(8\) {    padding: calc(8 * 1px)  }}

With the base order established, the utility's 8px padding wins over the component's 1.5rem. Without an enclosing layer, the native .card rule would remain unlayered and its normal padding would take precedence over the normal utility.

Keep layer blocks outside mixin bodies and @apply contents; those positions do not accept them. A layer selects ownership of the whole generated rule, rather than wrapping a fragment of declarations.

Priority within a layer

HTML class order does not choose the winner. Master CSS gives generated rules a stable order; the browser then applies the cascade to matching declarations. Within comparable layer, selector and condition contexts, generated rules are ordered as follows:

  1. Recipes with multiple declarations or inner selectors and conditions.

  2. Single-declaration utilities, including fixed, token-backed and direct-value utilities.

  3. Native declaration classes.

Single-declaration utilities sort by property family and coverage: a side or axis follows the whole family. For the same property and scope, named token values precede direct values. Importance, selector specificity and conditions still participate; a direct value does not universally defeat a token in another scope or layer.

The examples below use the preset, the base layer statement and a 16px root font size. Competing declarations target the same element and their conditions match.

Competing classes or rulesResultReason
p-md p(8), in either orderpadding: 8pxDirect value follows a token in the same property and scope
p(8) (padding:2rem), in either orderpadding: 2remNative declaration follows a single-declaration utility
m-md mt(0), in either orderTop margin 0; other margins 1remSide follows the whole margin family
b(2) bt(0) b-solid b-red-60Top width 0; other widths 2px; solid red borderWidth, style and color are independent families
p-md! p(8)padding: 1remImportance precedes value-source ordering
p-md! p(8)!padding: 8pxEqual importance; direct value follows token
p(8)@layer(base) p(12)padding: 12pxNormal utilities outrank base
p(8)@layer(base)! p(12)!padding: 8pxImportant declarations reverse layer precedence
Unlayered .outside { padding: 32px; } and p(8)padding: 32pxNormal unlayered declaration outranks layered declaration
Component-layer padding: 24px !important and p(8)!padding: 24pxEarlier layer wins between important declarations

Native rules in a layer retain their authored order; the generated-utility ordering above does not reorder those rules. Inspect the emitted CSS when declarations overlap, and use Code linting to catch conflicting classes during authoring.