Button
A flexible button with five variants, three accent colours, five sizes, four shapes, and icon-only mode.
Usage
<button class="zui-button">Click me</button>
<a href="/action" class="zui-button">Link as button</a> import { Button } from '@mrmartineau/zui/react'
<Button>Click me</Button>
<Button href="/action">Link as button</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button>Click me</Button>
<Button href="/action">Link as button</Button> import { Button } from '@mrmartineau/zui/solid'
<Button>Click me</Button>
<Button href="/action">Link as button</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button>Click me</Button>
<Button href="/action">Link as button</Button> <template>
<Button>Click me</Button>
<Button href="/action">Link as button</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Variants
Controls how the accent colour is applied.
<button class="zui-button">Fill (default)</button>
<button class="zui-button zui-button-variant-subtle">Subtle</button>
<button class="zui-button zui-button-variant-outline">Outline</button>
<button class="zui-button zui-button-variant-ghost">Ghost</button>
<button class="zui-button zui-button-variant-link">Link</button> import { Button } from '@mrmartineau/zui/react'
<Button>Fill (default)</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button>Fill (default)</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button> import { Button } from '@mrmartineau/zui/solid'
<Button>Fill (default)</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button>Fill (default)</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button> <template>
<Button>Fill (default)</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Accents
Sets the colour palette.
<button class="zui-button">Theme (default)</button>
<button class="zui-button zui-button-color-accent">Accent</button>
<button class="zui-button zui-button-color-destructive">Destructive</button> import { Button } from '@mrmartineau/zui/react'
<Button>Theme (default)</Button>
<Button color="accent">Accent</Button>
<Button color="destructive">Destructive</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button>Theme (default)</Button>
<Button color="accent">Accent</Button>
<Button color="destructive">Destructive</Button> import { Button } from '@mrmartineau/zui/solid'
<Button>Theme (default)</Button>
<Button color="accent">Accent</Button>
<Button color="destructive">Destructive</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button>Theme (default)</Button>
<Button color="accent">Accent</Button>
<Button color="destructive">Destructive</Button> <template>
<Button>Theme (default)</Button>
<Button color="accent">Accent</Button>
<Button color="destructive">Destructive</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Sizes
Five size options from extra small to extra large.
<button class="zui-button zui-button-size-xs">Extra small</button>
<button class="zui-button zui-button-size-sm">Small</button>
<button class="zui-button">Medium (default)</button>
<button class="zui-button zui-button-size-lg">Large</button>
<button class="zui-button zui-button-size-xl">Extra large</button> import { Button } from '@mrmartineau/zui/react'
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button>Medium (default)</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button>Medium (default)</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button> import { Button } from '@mrmartineau/zui/solid'
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button>Medium (default)</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button>Medium (default)</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button> <template>
<Button size="xs">Extra small</Button>
<Button size="sm">Small</Button>
<Button>Medium (default)</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra large</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Shapes
Controls border-radius. Includes squircle (limited browser support, uses corner-shape: superellipse).
<button class="zui-button">Default (rounded)</button>
<button class="zui-button zui-button-shape-hard">Hard (square)</button>
<button class="zui-button zui-button-shape-soft">Soft (pill)</button>
<button class="zui-button zui-button-shape-squircle">Squircle</button> import { Button } from '@mrmartineau/zui/react'
<Button>Default (rounded)</Button>
<Button shape="hard">Hard (square)</Button>
<Button shape="soft">Soft (pill)</Button>
<Button shape="squircle">Squircle</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button>Default (rounded)</Button>
<Button shape="hard">Hard (square)</Button>
<Button shape="soft">Soft (pill)</Button>
<Button shape="squircle">Squircle</Button> import { Button } from '@mrmartineau/zui/solid'
<Button>Default (rounded)</Button>
<Button shape="hard">Hard (square)</Button>
<Button shape="soft">Soft (pill)</Button>
<Button shape="squircle">Squircle</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button>Default (rounded)</Button>
<Button shape="hard">Hard (square)</Button>
<Button shape="soft">Soft (pill)</Button>
<Button shape="squircle">Squircle</Button> <template>
<Button>Default (rounded)</Button>
<Button shape="hard">Hard (square)</Button>
<Button shape="soft">Soft (pill)</Button>
<Button shape="squircle">Squircle</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Icon Buttons
Buttons for single icons. Uses the icon prop. Always include an aria-label.
<button class="zui-button zui-button-icon" aria-label="Settings">
<i class="ph ph-gear"></i>
</button>
<button class="zui-button zui-button-icon zui-button-variant-outline" aria-label="Edit">
<i class="ph ph-pencil-simple"></i>
</button>
<button class="zui-button zui-button-icon zui-button-variant-ghost" aria-label="Close">
<i class="ph ph-x"></i>
</button>
<button class="zui-button zui-button-icon zui-button-color-destructive" aria-label="Delete">
<i class="ph ph-trash"></i>
</button> import { Button } from '@mrmartineau/zui/react'
import { Gear, PencilSimple, X, Trash } from '@phosphor-icons/react'
<Button icon aria-label="Settings">
<Gear />
</Button>
<Button icon variant="outline" aria-label="Edit">
<PencilSimple />
</Button>
<Button icon variant="ghost" aria-label="Close">
<X />
</Button>
<Button icon color="destructive" aria-label="Delete">
<Trash />
</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button icon aria-label="Settings">
<i class="ph ph-gear"></i>
</Button>
<Button icon variant="outline" aria-label="Edit">
<i class="ph ph-pencil-simple"></i>
</Button>
<Button icon variant="ghost" aria-label="Close">
<i class="ph ph-x"></i>
</Button>
<Button icon color="destructive" aria-label="Delete">
<i class="ph ph-trash"></i>
</Button> import { Button } from '@mrmartineau/zui/solid'
<Button icon aria-label="Settings">
<i class="ph ph-gear"></i>
</Button>
<Button icon variant="outline" aria-label="Edit">
<i class="ph ph-pencil-simple"></i>
</Button>
<Button icon variant="ghost" aria-label="Close">
<i class="ph ph-x"></i>
</Button>
<Button icon color="destructive" aria-label="Delete">
<i class="ph ph-trash"></i>
</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button icon aria-label="Settings">
<i class="ph ph-gear"></i>
</Button>
<Button icon variant="outline" aria-label="Edit">
<i class="ph ph-pencil-simple"></i>
</Button>
<Button icon variant="ghost" aria-label="Close">
<i class="ph ph-x"></i>
</Button>
<Button icon color="destructive" aria-label="Delete">
<i class="ph ph-trash"></i>
</Button> <template>
<Button icon aria-label="Settings">
<i class="ph ph-gear"></i>
</Button>
<Button icon variant="outline" aria-label="Edit">
<i class="ph ph-pencil-simple"></i>
</Button>
<Button icon variant="ghost" aria-label="Close">
<i class="ph ph-x"></i>
</Button>
<Button icon color="destructive" aria-label="Delete">
<i class="ph ph-trash"></i>
</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Icon Button Sizes
Icon Button Shapes
Combining Variant + Accent
<button class="zui-button zui-button-variant-outline zui-button-color-accent">Outline Accent</button>
<button class="zui-button zui-button-variant-ghost zui-button-color-destructive">Ghost Destructive</button>
<button class="zui-button zui-button-variant-subtle zui-button-color-theme">Subtle Theme</button> import { Button } from '@mrmartineau/zui/react'
<Button variant="outline" color="accent">Outline Accent</Button>
<Button variant="ghost" color="destructive">Ghost Destructive</Button>
<Button variant="subtle" color="theme">Subtle Theme</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button variant="outline" color="accent">Outline Accent</Button>
<Button variant="ghost" color="destructive">Ghost Destructive</Button>
<Button variant="subtle" color="theme">Subtle Theme</Button> import { Button } from '@mrmartineau/zui/solid'
<Button variant="outline" color="accent">Outline Accent</Button>
<Button variant="ghost" color="destructive">Ghost Destructive</Button>
<Button variant="subtle" color="theme">Subtle Theme</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button variant="outline" color="accent">Outline Accent</Button>
<Button variant="ghost" color="destructive">Ghost Destructive</Button>
<Button variant="subtle" color="theme">Subtle Theme</Button> <template>
<Button variant="outline" color="accent">Outline Accent</Button>
<Button variant="ghost" color="destructive">Ghost Destructive</Button>
<Button variant="subtle" color="theme">Subtle Theme</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Kitchen Sink
<button class="zui-button zui-button-variant-outline zui-button-color-destructive zui-button-size-lg zui-button-shape-soft">
Large Pill Outline Destructive
</button> import { Button } from '@mrmartineau/zui/react'
<Button variant="outline" color="destructive" size="lg" shape="soft">
Large Pill Outline Destructive
</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button variant="outline" color="destructive" size="lg" shape="soft">
Large Pill Outline Destructive
</Button> import { Button } from '@mrmartineau/zui/solid'
<Button variant="outline" color="destructive" size="lg" shape="soft">
Large Pill Outline Destructive
</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button variant="outline" color="destructive" size="lg" shape="soft">
Large Pill Outline Destructive
</Button> <template>
<Button variant="outline" color="destructive" size="lg" shape="soft">
Large Pill Outline Destructive
</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> Variants × Accents
fill
subtle
outline
ghost
link
Sizes × Shapes
default
hard
soft
squircle
Disabled States
<button class="zui-button" disabled>Fill</button>
<button class="zui-button zui-button-variant-subtle" disabled>Subtle</button>
<button class="zui-button zui-button-variant-outline" disabled>Outline</button>
<button class="zui-button zui-button-variant-ghost" disabled>Ghost</button>
<button class="zui-button zui-button-color-destructive" disabled>Destructive</button> import { Button } from '@mrmartineau/zui/react'
<Button disabled>Fill</Button>
<Button variant="subtle" disabled>Subtle</Button>
<Button variant="outline" disabled>Outline</Button>
<Button variant="ghost" disabled>Ghost</Button>
<Button color="destructive" disabled>Destructive</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button disabled>Fill</Button>
<Button variant="subtle" disabled>Subtle</Button>
<Button variant="outline" disabled>Outline</Button>
<Button variant="ghost" disabled>Ghost</Button>
<Button color="destructive" disabled>Destructive</Button> import { Button } from '@mrmartineau/zui/solid'
<Button disabled>Fill</Button>
<Button variant="subtle" disabled>Subtle</Button>
<Button variant="outline" disabled>Outline</Button>
<Button variant="ghost" disabled>Ghost</Button>
<Button color="destructive" disabled>Destructive</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button disabled>Fill</Button>
<Button variant="subtle" disabled>Subtle</Button>
<Button variant="outline" disabled>Outline</Button>
<Button variant="ghost" disabled>Ghost</Button>
<Button color="destructive" disabled>Destructive</Button> <template>
<Button disabled>Fill</Button>
<Button variant="subtle" disabled>Subtle</Button>
<Button variant="outline" disabled>Outline</Button>
<Button variant="ghost" disabled>Ghost</Button>
<Button color="destructive" disabled>Destructive</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> As Links
<a href="/action" class="zui-button">Default link</a>
<a href="/action" class="zui-button zui-button-variant-outline zui-button-color-accent">Outline link</a>
<a href="/action" class="zui-button zui-button-variant-link">Text link</a> import { Button } from '@mrmartineau/zui/react'
<Button href="/action">Default link</Button>
<Button href="/action" variant="outline" color="accent">Outline link</Button>
<Button href="/action" variant="link">Text link</Button> ---
import { Button } from '@mrmartineau/zui/astro'
---
<Button href="/action">Default link</Button>
<Button href="/action" variant="outline" color="accent">Outline link</Button>
<Button href="/action" variant="link">Text link</Button> import { Button } from '@mrmartineau/zui/solid'
<Button href="/action">Default link</Button>
<Button href="/action" variant="outline" color="accent">Outline link</Button>
<Button href="/action" variant="link">Text link</Button> <script lang="ts">
import { Button } from '@mrmartineau/zui/svelte'
</script>
<Button href="/action">Default link</Button>
<Button href="/action" variant="outline" color="accent">Outline link</Button>
<Button href="/action" variant="link">Text link</Button> <template>
<Button href="/action">Default link</Button>
<Button href="/action" variant="outline" color="accent">Outline link</Button>
<Button href="/action" variant="link">Text link</Button>
</template>
<script setup>
import { Button } from '@mrmartineau/zui/vue'
</script> CSS custom properties
| Property | Default | Description |
|---|---|---|
--zui-btn-accent | var(--color-theme) | Accent colour used to derive button colours |
--zui-btn-radius | var(--radius-lg) | Border radius |
--zui-btn-border-style | solid | Border style |
--zui-btn-padding-block | var(--space-3xs) | Vertical padding |
--zui-btn-padding-inline | var(--space-xs) | Horizontal padding |
--zui-btn-height | 2rem | Minimum height |
--zui-btn-font-size | var(--step--1) | Font size |