Skip to content

Button

CSS onlyNo JavaScript No _defaults.js

Buttons are pure Tailwind utilities — each variant is a single class. There is no JavaScript and nothing to initialise; just add the class.

Button variants
Open ↗
components/buttons.html
<div class="flex flex-wrap items-center gap-3">
<button type="button" class="button-fill-primary"><span>Primary</span></button>
<button type="button" class="button-secondary">Secondary</button>
<button type="button" class="button-outline-primary">Outline</button>
<button type="button" class="button-tertiary">Tertiary</button>
<button type="button" class="button-ghost-foreground">Ghost</button>
</div>
<div class="mt-4 flex flex-wrap items-center gap-3">
<button type="button" class="button-fill-positive">Positive</button>
<button type="button" class="button-lightweight-negative">Delete</button>
<button type="button" class="button-lightweight-warning">Warning</button>
<button type="button" class="button-ghost-negative">Remove</button>
<button type="button" class="button-fill-primary" disabled><span>Disabled</span></button>
</div>
Class Role
button-fill-primary Primary action (gradient fill)
button-secondary Neutral secondary action
button-secondary-subtle Secondary with muted text
button-outline-primary Bordered primary
button-tertiary Low-emphasis brand action
button-ghost-foreground Text-only neutral
button-ghost-negative Text-only destructive
button-fill-positive Confirm / success
button-lightweight-negative Soft destructive
button-lightweight-warning Soft warning

Every variant is a flex row with gap-2 and sizes any <svg> inside to size-6, so icons drop straight in. Use an icon alone (add aria-label) or beside a label.

Icon buttons
Open ↗
components/buttons-icon.html
<div class="flex flex-wrap items-center gap-3">
<button type="button" class="button-fill-primary" aria-label="Add">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M12 5l0 14" />
<path d="M5 12l14 0" />
</svg>
</button>
<button type="button" class="button-secondary" aria-label="Edit">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1" />
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415" />
<path d="M16 5l3 3" />
</svg>
</button>
<button type="button" class="button-tertiary" aria-label="Download">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2" />
<path d="M7 11l5 5l5 -5" />
<path d="M12 4l0 12" />
</svg>
</button>
<button type="button" class="button-lightweight-negative" aria-label="Delete">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M4 7l16 0" />
<path d="M10 11l0 6" />
<path d="M14 11l0 6" />
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12" />
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3" />
</svg>
</button>
<button type="button" class="button-secondary">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M17 17h2a2 2 0 0 0 2 -2v-4a2 2 0 0 0 -2 -2h-14a2 2 0 0 0 -2 2v4a2 2 0 0 0 2 2h2" />
<path d="M17 9v-4a2 2 0 0 0 -2 -2h-6a2 2 0 0 0 -2 2v4" />
<path d="M7 15a2 2 0 0 1 2 -2h6a2 2 0 0 1 2 2v4a2 2 0 0 1 -2 2h-6a2 2 0 0 1 -2 -2l0 -4" /></svg
><span>Print</span>
</button>
</div>

All variants share a base style, so you get these for free:

  • Press feedbackactive:scale-95.
  • Disabled — add the disabled attribute; it dims and blocks pointer events.
  • Focus ring — a visible focus state via focus-visible.
  • Icon sizing — any child <svg> becomes size-6 automatically.