Primary
Reserve the strongest emphasis for the main action. Demo buttons do not save or submit data.
View Code
<button class="btn" type="button">
Create Project
</button>Primary and secondary actions.
Reserve the strongest emphasis for the main action. Demo buttons do not save or submit data.
<button class="btn" type="button">
Create Project
</button>Use secondary for alternatives and ghost for low-priority actions.
<div class="cluster">
<button class="btn secondary" type="button">
Preview
</button>
<button class="btn ghost" type="button">
Cancel
</button>
</div>Keep text where practical. Icon-only buttons need an accessible name and retain a 44px target.
<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>Default targets are at least 44px tall; large targets are 52px. Rounded rectangles remain the default for actions.
<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>Native disabled prevents activation and removes the button from the tab order. Explain why the action is unavailable.
<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>Static state example. Your application sets and clears disabled and aria-busy around its request. Announce completion in a separate status region.
<button class="btn" type="button" disabled aria-busy="true">
Saving…
</button>Labels wrap rather than overflowing at narrow widths or enlarged text sizes. Prefer concise action names.
<div style="max-inline-size:10rem">
<button class="btn" type="button">
Review Project Settings
</button>
</div>Content order follows the reading direction. Translate labels and mirror only directional icons.
<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>Hover and press feedback changes color without movement. This example opts out of transitions; reduced-motion preferences also disable them.
<button class="btn" type="button" data-motion="none">
Preview
</button>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.
<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
Use button for actions and an anchor with a real href for navigation. Set the button’s type explicitly.
Start with .btn. Add .secondary or .ghost for quieter actions; use .btn-large, .btn-icon, or .btn-pill when needed.
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.
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.