Purpose
Buttons trigger actions (submit a form, open a dialog, load more content). They are the most common interactive element and the correct baseline for all custom interactive controls.
Usage Guidance
- Use
<button>for actions; use<a>for navigation - Buttons that submit forms use
type="submit"; all other buttons usetype="button" - Button labels must be descriptive: “Delete audit record” not just “Delete”
- Icon-only buttons must have an accessible name via
aria-label
Accessibility Considerations
- Native
<button>provides keyboard support, role, and state announcement for free - Never use
<div>,<span>, or<a>as a button without extensive ARIA reconstruction - Disabled buttons should use the
disabledattribute; usearia-disabled="true"only when you need to keep them focusable - Loading state buttons should update
aria-labelto indicate loading (e.g., “Saving, please wait”)
Keyboard Support
| Key | Action |
|---|---|
Tab / Shift+Tab |
Move focus to/from the button |
Enter or Space |
Activate the button |
Screen Reader Behavior
Screen readers announce the button’s label and role (e.g., “Save changes, button”). State changes (disabled, pressed) are announced when focus is on the button.
ARIA Requirements
aria-labelfor icon-only buttonsaria-pressed="true|false"for toggle buttonsaria-expanded="true|false"for buttons that control show/hide regionsaria-disabled="true"only when thedisabledattribute cannot be used
Common Mistakes
- Using
<a href="#">for buttons - Missing accessible names on icon-only buttons
- Not announcing loading or processing states
- Using
pointer-events: noneas a “disabled” state without using thedisabledattribute
Live Examples
Code Examples
<!-- Standard button -->
<button class="btn btn--primary" type="button">Save Changes</button>
<!-- Icon-only button -->
<button class="btn" type="button" aria-label="Delete audit record">
<svg aria-hidden="true" focusable="false"><!-- icon --></svg>
</button>
<!-- Toggle button -->
<button
class="btn btn--blue"
type="button"
aria-pressed="false"
>
Bookmark
</button>
<!-- Button that opens a dialog -->
<button
class="btn btn--primary"
type="button"
aria-haspopup="dialog"
data-dialog-open="my-dialog"
>
Open Dialog
</button>
<!-- Disabled button -->
<button class="btn btn--primary" type="button" disabled>
Save (Disabled)
</button>
.btn {
display: inline-flex; align-items: center; gap: 0.5rem;
padding: 0.75rem 1.5rem; font-size: 1rem; font-weight: 600;
border-radius: 0.5rem; border: 2px solid transparent;
cursor: pointer; text-decoration: none;
transition: background 150ms ease, color 150ms ease;
}
.btn:focus-visible {
outline: 3px solid #d4700a;
outline-offset: 3px;
}
.btn[disabled] {
opacity: 0.5; cursor: not-allowed; pointer-events: none;
}
.btn--primary { background: #1a7a6e; color: #fff; border-color: #1a7a6e; }
.btn--primary:hover { background: #155f55; }