Zazz Design Framework
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):

FilePurposeDocumentation
_layers.cssDeclares cascade layer order (loads first)Layers
_variables.cssGlobal design tokens (colors, type, spacing, metrics)Theme variables
_reset.cssNative element baselines and zero-specificity control resetsReset
_typography.cssType scale, .ui-prose, and typography utilitiesTypography
_view-transitions.cssCross-document and SPA view transitionsView transitions
_utilities.cssAtomic utility classesUtilities
_layout.cssContainer bands and layout grid utilitiesLayout

Component file structure

Component stylesheets organize rules in top-to-bottom order:

StepSectionLayerCondition
1CSSDoc headerNoneAlways
2Component token hooks@layer variablesWhen component exposes tokens
3Native element baselines@layer resetWhen restyling native UI
4Component rules@layer zazz.componentsCore component rules
5Utility classes@layer zazz.utilitiesWhen 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

TagRequiredDescription
SummaryYesFirst line: file.css: Component (.ui-selector)
@layerYesCascade layers used in the file
@requiresYesDependency files (set to none for layers.css)
@usesOptionalModern CSS features or APIs utilized
@tokensOptionalToken namespace exposed
@consumedbyOptionalDependent files
@seeOptionalExternal references
@exampleOptionalHTML 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-height is the exception (that is the property name), and a bare -size names 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 -border shorthand 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 like class, 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 carry data-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.

On this page