CSS Layers
ZUI uses @layer to organise its styles into a predictable cascade, making it easy to override without specificity battles.
Layer order
All ZUI styles are scoped inside four ordered layers, declared at the top of the stylesheet:
@layer zui.reset, zui.base, zui.components, zui.utilities;
Layers declared later in the list have higher priority. This means utilities always beat components, components always beat base styles, and so on.
What lives in each layer
zui.reset
A lightweight reset that normalises browser defaults. Sets box-sizing: border-box, removes margins, and ensures media elements are block-level with max-width: 100%.
@layer zui.reset {
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
}
zui.base
The foundation layer containing:
- Design tokens — colour palettes, spacing scale, type scale, font stacks, font weights, line heights, letter spacing, radii, shadows, easing, z-index, and aspect ratios
- Theme configuration — semantic colour mappings, font assignments, radius scale, and border style
- Base styles — root element defaults (
color-scheme, font family, background, text colour), selection styling, and reduced-motion preferences
zui.components
All component styles: button, input, textarea, select, label, radio, checkbox, card, and badge. Each component file wraps its rules in @layer zui.components.
zui.utilities
Helper classes for typography (.zui-text-*), links (.zui-link), code (.zui-code, .zui-pre), colour utilities, spacing, flex, and layout. These sit at the top of the cascade so they can reliably override component defaults.
File structure
The layer order maps directly to the import order in index.css:
@import './layers.css'; /* declares layer order */
@import './reset.css'; /* → zui.reset */
@import './tokens.css'; /* → zui.base (design tokens) */
@import './theme.css'; /* → zui.base (semantic mappings) */
@import './core.css'; /* → zui.base (element defaults) */
@import './components.css'; /* → zui.components */
@import './utilities.css'; /* → zui.utilities */
@import './print.css'; /* print media query (unlayered) */
Overriding ZUI styles
Because all ZUI styles live inside layers, any unlayered CSS you write will automatically take precedence — no !important needed.
/* This wins over any ZUI layer, regardless of specificity */
.my-custom-button {
background-color: hotpink;
border-radius: 0;
}
If you prefer to stay within the layer system, you can target a specific layer:
/* Override within the components layer */
@layer zui.components {
.zui-button {
--zui-btn-radius: 0;
}
}
/* Or add your own layer after ZUI's layers */
@layer zui.reset, zui.base, zui.components, zui.utilities, app;
@layer app {
.my-override {
color: red;
}
}
Integrating with other libraries
If you're using another CSS library alongside ZUI, you can control the cascade by declaring all layers upfront:
/* Declare order: ZUI layers first, then your app layer */
@layer zui.reset, zui.base, zui.components, zui.utilities, app;
@import '@mrmartineau/zui/css';
/* Your styles in the app layer will beat ZUI's utilities */
@layer app {
.hero-title {
font-size: 4rem;
}
}