Usage approaches

Plain CSS classes

Every component is usable with any HTML element by applying the right class names. This works in any framework or with no framework at all.

<button class="zui-button zui-button-variant-outline">Click me</button>

React

React wrappers accept typed props instead of class strings. Import from @mrmartineau/zui/react.

import { Button } from '@mrmartineau/zui/react'

<Button variant="outline">Click me</Button>

Astro

Astro wrappers work the same way. Import from @mrmartineau/zui/astro.

---
import { Button } from '@mrmartineau/zui/astro'
---

<Button variant="outline">Click me</Button>

Solid

Solid wrappers use class instead of className. Import from @mrmartineau/zui/solid.

import { Button } from '@mrmartineau/zui/solid'

<Button variant="outline">Click me</Button>

Svelte

Svelte wrappers are Svelte 5 SFCs that use runes and snippets. Import from @mrmartineau/zui/svelte.

<script lang="ts">
  import { Button } from '@mrmartineau/zui/svelte'
</script>

<Button variant="outline">Click me</Button>

Vue

Vue wrappers are SFC components. Import from @mrmartineau/zui/vue.

<template>
  <Button variant="outline">Click me</Button>
</template>

<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script>

See Using with React, Using with Astro, Using with Solid, Using with Svelte, and Using with Vue for setup instructions.

CSS layer

Component styles live in the zui.components layer, below zui.utilities. This means utility classes always override component styles when both apply, without needing !important.

@layer zui.base, zui.components, zui.utilities;

CSS custom properties

Every component exposes CSS custom properties (variables) that control its appearance — colours, border radius, padding, shadow, and more. You can override these without touching the source CSS and without ejecting any styles.

Inline overrides

Pass overrides via the style attribute on the component's root element:

<div class="zui-card" style="--zui-card-radius: var(--radius-sm); --zui-card-padding: var(--space-lg);">

</div>

CSS overrides

Target the component class in your own stylesheet. Because component styles live in zui.components, any rule outside a @layer already wins — no !important needed:

.zui-card {
  --zui-card-radius: var(--radius-sm);
  --zui-card-padding: var(--space-lg);
}

To scope an override to a specific context, nest it under a parent selector:

.my-sidebar .zui-button {
  --zui-btn-radius: 0;
}

See this live CodePen example showing three cards side by side: one with default styles, one customised via inline style attributes, and one themed via scoped CSS classes. Each component page lists its available custom properties and their defaults.

Components

Accordion

A stacked set of disclosure panels using the native details/summary elements.

Avatar

A circular image with a fallback for when the image fails to load or no source is provided.

Badge

Small status indicators and labels. Supports colour variants and size modifiers.

Button

A flexible button with five variants, three accent colours, five sizes, four shapes, and icon-only mode.

Card

A container for grouping related content, with optional header, body, and footer sections.

Checkbox

Custom-styled checkboxes with list layout.

Collapsible

A single disclosure widget using the native details/summary elements.

Dialog

Modal dialogs built on the native dialog element with a styled backdrop. Requires minimal JavaScript to open.

Flex

A layout component for flexbox-based arrangements. Controls direction, alignment, justification, wrapping, and gap spacing via props.

Input

A styled text input for forms.

Label

Form labels with optional required indicator and description text.

Menu

A strict action menu with managed focus, keyboard navigation, and menu button semantics.

Popover

Floating panels built on the native HTML Popover API and CSS Anchor Positioning. No JavaScript required.

Radio

Custom-styled radio buttons with list layout.

Select

A styled native select dropdown.

Table

A styled table for displaying tabular data.

Tabs

Accessible tabs with horizontal and vertical orientations.

Textarea

A multi-line text input with auto-sizing via field-sizing: content.

Tooltip

Small contextual labels on hover or focus, using the Popover API and CSS Anchor Positioning.

Theme

Copy this CSS to your project: