ZUI ships first-party wrappers for React, Astro, Solid, Svelte, and Vue. For other frameworks, use the CSS classes directly.

Install ZUI and import the stylesheet however your framework handles CSS

CSS class reference

All ZUI components use BEM-style classes prefixed with zui-. Apply them directly in any template language.

Button

ClassPurpose
zui-buttonBase button styles
zui-button-variant-fillSolid filled button (default)
zui-button-variant-subtleSubtle background
zui-button-variant-outlineOutlined border
zui-button-variant-ghostNo background until hover
zui-button-variant-linkLooks like a text link
zui-button-color-themeTheme colour (default)
zui-button-color-accentAccent colour
zui-button-color-destructiveDestructive/danger colour
zui-button-size-xsExtra small
zui-button-size-smSmall
zui-button-size-lgLarge
zui-button-size-xlExtra large
zui-button-shape-hardSharp corners
zui-button-shape-softExtra rounded corners
zui-button-shape-squircleSquircle shape
zui-button-iconIcon-only button (square)

Badge

ClassPurpose
zui-badgeBase badge styles
zui-badge-variant-fillSolid filled badge
zui-badge-variant-outlineOutlined badge
zui-badge-color-{color}Color variant (red, green, blue, violet, amber, orange, yellow, lime, emerald, teal, cyan, sky, indigo, purple, fuchsia, pink, rose, gray)

Card

ClassPurpose
zui-cardBase card container
zui-card-elevatedElevated shadow style
zui-card-interactiveAdds hover/focus styles for clickable cards
zui-card-headerCard header section
zui-card-titleCard title text
zui-card-descriptionCard description text
zui-card-bodyCard body content
zui-card-footerCard footer section

Form elements

ClassPurpose
zui-inputText input
zui-textareaTextarea
zui-selectSelect dropdown
zui-labelForm label
zui-label-requiredAdds a required indicator after the label
zui-label-descriptionDescriptive/hint text below a label
zui-checkboxCheckbox
zui-checkbox-listVertical list of checkboxes
zui-radioRadio button
zui-radio-listVertical list of radio buttons

Table

ClassPurpose
zui-tableBase table styles
zui-table-headTable header cell (<th>)
zui-table-rowTable row
zui-table-cellTable body cell (<td>)
zui-table-footerTable footer row/section
zui-table-captionTable caption

Dialog

ClassPurpose
zui-dialogDialog container
zui-dialog-headerDialog header section
zui-dialog-titleDialog title text
zui-dialog-descriptionDialog description text
zui-dialog-bodyDialog body content
zui-dialog-footerDialog footer section
zui-dialog-closeClose button
zui-dialog-size-smSmall dialog
zui-dialog-size-lgLarge dialog
zui-dialog-size-fullFull-screen dialog

Tooltip

ClassPurpose
zui-tooltipTooltip wrapper
zui-tooltip-contentTooltip content bubble
zui-tooltip-placement-topPosition above the trigger
zui-tooltip-placement-bottomPosition below the trigger
zui-tooltip-placement-leftPosition left of the trigger
zui-tooltip-placement-rightPosition right of the trigger

Accordion

ClassPurpose
zui-accordionAccordion container
zui-accordion-itemIndividual accordion item (<details>)
zui-accordion-triggerAccordion toggle (<summary>)
zui-accordion-contentAccordion content panel
zui-accordion-flushFlush (borderless) variant

Collapsible

ClassPurpose
zui-collapsibleCollapsible container (<details>)
zui-collapsible-triggerToggle trigger (<summary>)
zui-collapsible-contentCollapsible content panel

Popover

ClassPurpose
zui-popoverPopover container

Framework examples

Plain HTML

<button class="zui-button zui-button-variant-fill zui-button-color-theme">
  Save
</button>

<span class="zui-badge zui-badge-color-green">Active</span>

<div class="zui-card">
  <div class="zui-card-header">
    <h2 class="zui-card-title">Card title</h2>
    <p class="zui-card-description">Card description</p>
  </div>
  <div class="zui-card-body">
    <label class="zui-label" for="email">Email</label>
    <input class="zui-input" id="email" type="email" />
    <button class="zui-button zui-button-variant-outline">Submit</button>
  </div>
</div>

Utility classes

ZUI ships utility classes you can use in any framework. Note that spacing, flex, flow, and prose utilities do not use the zui- prefix.

Spacing

<!-- Margin -->
<div class="mt-md mx-lg">...</div>

<!-- Padding -->
<div class="px-lg py-sm">...</div>

<!-- Gap (for flex/grid) -->
<div class="flex flex-row gap-md">...</div>

Flex

<div class="flex flex-row gap-md items-center">...</div>
<div class="flex flex-column gap-sm">...</div>
<div class="inline-flex items-center gap-xs">...</div>

Layout

<!-- Flow (vertical rhythm) -->
<div class="flow">...</div>

<!-- Prose (long-form content) -->
<div class="prose">...</div>

Typography

<!-- Font size scale -->
<p class="zui-text-sm">Small text</p>
<p class="zui-text-base">Base text</p>
<p class="zui-text-1">Larger text</p>

<!-- Muted text -->
<p class="zui-color-muted">Secondary text</p>
<p class="zui-color-faint">Faint text</p>

<!-- Link styling -->
<a href="#" class="zui-link">Styled link</a>

<!-- Code -->
<code class="zui-code">inline code</code>
<pre class="zui-pre"><code>block code</code></pre>

Accessibility

<!-- Visually hidden (screen reader only) -->
<span class="sr-only">Screen reader label</span>

Building wrapper components

You can create thin wrapper components in any framework using the CSS classes. Here's a generic example using a hypothetical template language:

<!-- Button.template -->
<button class="zui-button zui-button-variant-{variant} zui-button-color-{color}">
  {label}
</button>

Tip: ZUI already ships first-party wrappers for React, Astro, Solid, Svelte, and Vue.

CSS Layers

ZUI uses CSS @layer to organize styles. Your unlayered styles will always take precedence, making overrides straightforward in any framework:

/* Your framework's styles — always wins over ZUI layers */
.my-custom-button {
  background-color: hotpink;
}

Theming

Theming is framework-agnostic — just override CSS custom properties. See the Theming page for full details.

:root {
  --color-theme: light-dark(var(--color-violet-600), var(--color-violet-400));
  --radius-scale: 1.5;
}

Theme

Copy this CSS to your project: