Browse Components

Buttons

Primary and secondary actions.

Primary

Reserve the strongest emphasis for the main action. Demo buttons do not save or submit data.

View Code
HTML
<button class="btn" type="button">
  Create Project
</button>

Emphasis

Use secondary for alternatives and ghost for low-priority actions.

View Code
HTML
<div class="cluster">
  <button class="btn secondary" type="button">
    Preview
  </button>
  <button class="btn ghost" type="button">
    Cancel
  </button>
</div>

Icons

Keep text where practical. Icon-only buttons need an accessible name and retain a 44px target.

View Code
HTML
<div class="cluster">
  <button class="btn" type="button">
    <svg
      aria-hidden="true"
      focusable="false"
      xmlns="http://www.w3.org/2000/svg"
      viewbox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="1.75"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <path d="M12 5v14M5 12h14">
      </path>
    </svg>
    New Project
  </button>
  <button class="btn secondary btn-icon" type="button" aria-label="Add Project">
    <svg
      aria-hidden="true"
      focusable="false"
      xmlns="http://www.w3.org/2000/svg"
      viewbox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="1.75"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <path d="M12 5v14M5 12h14">
      </path>
    </svg>
  </button>
</div>

Size and shape

Default targets are at least 44px tall; large targets are 52px. Rounded rectangles remain the default for actions.

View Code
HTML
<div class="cluster">
  <button class="btn" type="button">
    Default
  </button>
  <button class="btn btn-large" type="button">
    Large
  </button>
  <button class="btn btn-pill" type="button">
    Pill
  </button>
</div>

Disabled

Native disabled prevents activation and removes the button from the tab order. Explain why the action is unavailable.

Add a title before publishing.

View Code
HTML
<div class="stack">
  <button class="btn" type="button" disabled aria-describedby="publish-help">
    Publish
  </button>
  <p id="publish-help">
    Add a title before publishing.
  </p>
</div>

Busy state

Static state example. Your application sets and clears disabled and aria-busy around its request. Announce completion in a separate status region.

View Code
HTML
<button class="btn" type="button" disabled aria-busy="true">
  Saving…
</button>

Long labels

Labels wrap rather than overflowing at narrow widths or enlarged text sizes. Prefer concise action names.

View Code
HTML
<div style="max-inline-size:10rem">
  <button class="btn" type="button">
    Review Project Settings
  </button>
</div>

Right-to-left

Content order follows the reading direction. Translate labels and mirror only directional icons.

View Code
HTML
<div dir="rtl" lang="he">
  <button class="btn" type="button">
    <svg
      aria-hidden="true"
      focusable="false"
      xmlns="http://www.w3.org/2000/svg"
      viewbox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="1.75"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <path d="M12 5v14M5 12h14">
      </path>
    </svg>
    פרויקט חדש
  </button>
</div>

Without motion

Hover and press feedback changes color without movement. This example opts out of transitions; reduced-motion preferences also disable them.

View Code
HTML
<button class="btn" type="button" data-motion="none">
  Preview
</button>

Installation

Download these files into the matching paths in your project, or use Create to assemble a kit. Include each dependency once. Do not also load app.css.

Add to your page
<link rel="stylesheet" href="/library/assets/base.css">
<link rel="stylesheet" href="/library/assets/button.css">

10,224 bytes CSS including base · 0 bytes runtime JavaScript

Usage

Choose the right element

Use button for actions and an anchor with a real href for navigation. Set the button’s type explicitly.

Choose an emphasis

Start with .btn. Add .secondary or .ghost for quieter actions; use .btn-large, .btn-icon, or .btn-pill when needed.

Handle states clearly

Label icon-only buttons. Use disabled for unavailable buttons, and visible progress text with aria-busy while working. Your app handles requests and errors.

Building with AI? The AI Manifest has these notes and the full contract. See the AI Guide.

Framework integrations

Use this shared component standalone or through the tested React, Next.js, Vue, Nuxt, Angular, Svelte, and Astro integration paths. Keep application state in your framework; adapters handle native behavior and cleanup.

View Integration APIs and Working Examples. For dialogs, choose either the adapter controller or the standalone initializer, never both on the same element.