Cascade Layers
Rely on layers to eliminate style overrides and conflicts.
Understanding all layers
Master CSS analyzes the syntax and inserts it into the appropriate layer, allowing you to focus on the UI without worrying about style precedence.
Layer | Description | Entity |
---|---|---|
Base | Where the styles with @base are generated. | @layer base { … } |
Theme | Where the used variables are generated. | @layer theme { … } |
Preset | Where the styles with @preset are generated. | @layer preset { … } |
Components | Where the used components are generated. | @layer components { … } |
General | Where the general styles are generated. | @layer general { … } |
Here is an example that covers all layers:
export default { variables: { primary: { '@light': '#000000', '@dark': '#ffffff' } }, components: { btn: 'inline-flex bg:primary' }}
<body class="list-style:none_ul@base"> <button class="btn flex">Submit</button> <ul class="@fade|1s">…</ul> <article class="text:16_p@preset"> <p>…</p> </article></body>
Generated CSS:
@layer base, theme, preset, components, general;@layer base { .list-style\:none_ul\@base ul { list-style: none }}@layer theme { .light, :root { --primary: 0 0 0 } .dark { --primary: 255 255 255 }}@layer preset { .text\:16_p\@preset p { font-size: 1rem; line-height: calc(1rem + 0.875em) }}@layer components { .btn { display: inline-flex; background-color: rgb(var(--primary)) }}@layer general { .flex { display: flex } .\@fade\|1s { animation: fade 1s }}@keyframes fade { 0% { opacity: 0 } to { opacity: 1 }}
- The first line defines the cascade order. Layers declared later will override earlier ones in case of conflicts.
- Base — rules from
@base
(e.g.,list-style:none_ul@base
). - Theme — rules from variables and
config.variables
. - Preset — rules from
@preset
syntax (e.g.,text:16_p@preset
). - Components — rules from abstract components and
config.components
. - General — rules from common utilities (e.g.,
flex
,@fade|1s
). - All keyframes are placed at the top level.
Adding base styles
To normalize browser and preset global styles for more concise-style programming, add CSS rules in the base layer.
Add a CSS rule for base styles in your global CSS file
@layer base { ul { list-style: none; }}
Or you can add base styles with @base
in the HTML:
<body class="list-style:none_ul@base">…</body>
Generated CSS:
@layer base, theme, preset, components, general;@layer base { .list-style\:none_ul\@base ul { list-style: none }}
In most cases, the official package, @master/normal.css
, can help you normalize browser styles.
Adding preset styles
To preset fonts, foreground colors, etc. based on your brand, use @preset
to define these styles in elements.
Use selectors and @preset
to preset styles for elements and states.
<body class="font:mono_:is(code,pre)@preset">…</body>
Generated CSS:
@layer base, theme, preset, components, general;@layer preset { .font\:mono_\:is\(code\,pre\)\@preset :is(code, pre) { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace }}
Without @preset
, you would have to always add !important
whenever you customize the same CSS property for the selected element.
Don't add brand-related preset styles to the base layer.
<body class="font:mono_:is(code,pre)@base">…</body>
The preset layer styles should be built on top of the base layer.
Overriding component styles
You can override the components by adding general syntax, without having to prioritize rules.
For example, add flex
to override the display declaration inline-flex
of the button.
<button class="btn flex">Submit</button>
Generated CSS:
@layer base, theme, preset, components, general;@layer components { .btn { display: inline-flex; … }}@layer general { .flex { display: flex; }}
Overriding preset styles
You can select descendants with @preset
to preset styles, preventing component and general styles from being overwritten.
For example, set the default paragraph text size to 16
and change the text size of a specific paragraph to 24
.
<article class="text:16_p@preset"> <p class="text:24">24</p> <p>16</p></article>
Generated CSS:
@layer base, theme, preset, components, general;@layer preset { .text\:16_p\@preset p { font-size: 1rem; line-height: calc(1rem + 0.875em) }}@layer general { .text\:24 { font-size: 1.5rem; line-height: calc(1.5rem + 0.875em) }}
This way, you can set preset styles for multiple targets at once while still being able to modify specific elements' styles as needed.
Summary
By leveraging CSS cascade layers, you can structure your styles for better maintainability and prevent unwanted overrides.
If styles conflict, the order of priority: General > Components > Theme > Preset > Base.
Responsibilities
- Use the base layer for global resets and normalization.
- Use the preset layer for brand-specific defaults.
- Other layers are automatically generated based on your syntax and configuration.
Best Practices
- Create base styles via CSS files and packages instead of defining a lot of
@base
syntax. - Create preset styles based on base styles.
- Create component styles based on base and preset styles.