base
File anatomy
File structure, layer placement, CSSDoc headers, and naming conventions for Zazz stylesheets.
Stylesheets in @zazz-ui/core follow consistent organization across base modules and components.
Base files
Source files split into base/ (core foundation) and ui/ (co-located component stylesheets, scripts, and markup):
| File | Purpose | Documentation |
|---|---|---|
_layers.css | Declares cascade layer order (loads first) | Layers |
_variables.css | Global design tokens (colors, type, spacing, metrics) | Theme variables |
_reset.css | Native element baselines and zero-specificity control resets | Reset |
_typography.css | Type scale, .ui-prose, and typography utilities | Typography |
_view-transitions.css | Cross-document and SPA view transitions | View transitions |
_utilities.css | Atomic utility classes | Utilities |
_layout.css | Container bands and layout grid utilities | Layout |
Component file structure
Component stylesheets organize rules in top-to-bottom order:
| Step | Section | Layer | Condition |
|---|---|---|---|
| 1 | CSSDoc header | None | Always |
| 2 | Component token hooks | @layer variables | When component exposes tokens |
| 3 | Native element baselines | @layer reset | When restyling native UI |
| 4 | Component rules | @layer zazz.components | Core component rules |
| 5 | Utility classes | @layer zazz.utilities | When shipping utilities |
/**
* button.css: Button (.ui-button)
*
* @layer variables, components
* @requires layers.css, _variables.css, _reset.css
* @uses color-mix(), oklch(from ...) (hover/active tints)
* @tokens --ui-button-* (@layer variables)
*/
@layer variables {
:root {
--ui-button-background: var(--card);
--ui-button-block-size: var(--step-8);
--ui-button-radius: var(--radius-md);
}
}
@layer zazz.components {
.ui-button {
background-color: var(--ui-button-background);
min-block-size: var(--ui-button-block-size);
border-radius: var(--ui-button-radius);
}
}CSSDoc header tags
| Tag | Required | Description |
|---|---|---|
| Summary | Yes | First line: file.css: Component (.ui-selector) |
@layer | Yes | Cascade layers used in the file |
@requires | Yes | Dependency files (set to none for layers.css) |
@uses | Optional | Modern CSS features or APIs utilized |
@tokens | Optional | Token namespace exposed |
@consumedby | Optional | Dependent files |
@see | Optional | External references |
@example | Optional | HTML usage example |
Token naming conventions
- Default token:
--ui-{component}-{property}(e.g.--ui-button-background,--ui-dialog-radius). - State variation:
--ui-{component}-{property}--{state}with double-dash (e.g.--ui-button-background--hover,--ui-field-border-color--focus). - Logical property names: a token is named after the CSS property it feeds, in its logical form —
--ui-field-block-size, never--ui-field-height;--ui-toaster-inline-size, never--ui-toaster-width.-line-heightis the exception (that is the property name), and a bare-sizenames square dimensions (--ui-checkbox-size,--ui-button-icon-size). - Border tokens: interactive controls expose
-border-width/-border-style/-border-color(plus-border-color--{state}) so any part can be retuned independently; decorative, non-varying borders keep a single-bordershorthand token (--ui-table-border,--ui-dialog-border). - Cross-component defaults: a component token may default to another component's token so families stay in sync — button metrics default to the shared
--ui-field-*family, and toggle defaults to--ui-button-*.
Selector conventions
- Roots: a single
.ui-{component}class (e.g..ui-button,.ui-dialog). Primitives whose root would otherwise be a generic<div>also have an equivalent tag form:<ui-tooltip>matches the same rules as<div class="ui-tooltip">via:where(ui-tooltip, .ui-tooltip)aliasing. Classes only ever name roots. - Slots (interior parts):
data-slot="{component}-{part}"(e.g.data-slot="dialog-header",data-slot="carousel-viewport"). The attribute is a space-separated token list likeclass, so one element can serve two primitives (data-slot="lightbox-slide carousel-slide"); selectors always use the token matcher[data-slot~="carousel-slide"]. Roots never carrydata-slot. - Variants and state: Data attributes, never modifier classes (e.g.
[data-variant="primary"],[data-size="sm"],[data-side]). - Zero specificity:
:where()on reset and utility selectors. - Logical properties:
inline-size,block-size,padding-inline,margin-block. - State exclusion:
:not(:disabled)over order-dependent overrides.