Zazz Design Framework
Core concepts

Adding custom styles

Extend Zazz without modifying core files using token overrides, custom cascade layers, and unlayered CSS.

Extend Zazz by loading custom styles after index.css:

<link rel="stylesheet" href="./zazz/index.css" /> <link rel="stylesheet" href="./your-styles.css" />

1. Token overrides

Most customizations require updating variables rather than writing new rules:

/* your-styles.css */
:root {
  --primary: oklch(0.6 0.2 145); /* global brand override */
  --ui-button-radius: var(--radius-full); /* component default override */
}
<!-- instance override -->
<div class="bg-card text-card-foreground rounded-md" style="--card: var(--muted)">...</div>

Token overrides preserve theme switching and layer relationships.

2. Custom utility classes

Add custom utilities inside @layer zazz.utilities. Wrap selectors in :where() to maintain zero specificity:

@layer zazz.utilities {
  :where(.text-gradient) {
    background: linear-gradient(90deg, var(--primary), var(--secondary));
    background-clip: text;
    color: transparent;
  }
}

3. Custom components

Author new components inside @layer zazz.components using design tokens:

@layer zazz.components {
  :where(.callout) {
    --callout-background: var(--muted);
    background: var(--callout-background);
    border-inline-start: var(--step-1) solid var(--primary);
    padding: var(--gap-md);
    border-radius: var(--radius-md);
  }
}

Utilities will override component properties as expected.

4. Unlayered CSS

Rules written outside of any @layer beat all layered rules in Zazz:

.ui-button {
  border-radius: 0;
}

Use unlayered CSS only when intentionally bypassing the cascade layer order.

Hierarchy of customization

  1. Token overrides: Best for colors, spacing, radius, and sizing.
  2. Layered rules: Best for reusable utilities and custom components.
  3. Unlayered rules: For absolute overrides across the system.

On this page