Button
GuidancelatestcurrentRetrieved 2026-05-12
Primer — Button
Overview
Button is used to initiate actions on a page or form. At GitHub, buttons are a fundamental building block. Most interactions use the secondary variant; other variants communicate hierarchy or specific functionality.
Anatomy
A button consists of up to four elements:
| Element | Required | Description |
|---|---|---|
| Label | Yes | Text describing the action; serves as the accessible name |
| Leading visual | No | Icon before the label providing additional context |
| Trailing visual | No | Counters or supplementary information after the label |
| Trailing action | No | Dropdown caret or similar; always locked to the end of the button |
Trailing action alignment: A call-to-action button (Submit, Save) has label and visuals center-aligned. A selection button (Sort ▾, Weeks ▾) has contents left-aligned inside the container.
Variants
| Variant | Background | Use |
|---|---|---|
| Primary | bgColor-success-emphasis (green) | Highest-priority action. Only one per page or button group. |
| Secondary | bgColor-default (neutral) | Default for most interactions. Can pair with primary. |
| Danger | bgColor-danger-emphasis (red) | Destructive actions. Typically opens a confirmation dialog. |
| Invisible | Transparent | Transparent background with translucent hover/active states. Used in compound components like ActionList. |
| Inactive | Muted styling | Non-functional button that remains on screen. Unlike disabled, it responds to input (can show tooltips or dialogs). |
| Loading | — | Replaces label with a spinner while an action is processing. |
Sizing
| Size | Height | Use |
|---|---|---|
| Small | — | Limited space, less significant actions |
| Medium (default) | — | Preferred for most interfaces |
| Large | — | Emphasizes action significance; use sparingly |
States
| State | Visual | Notes |
|---|---|---|
| Rest | Variant default colors | |
| Hover | Translucent state layer overlay | |
| Focus | 2px focus ring (focus-outlineColor) | Required; must be visible on keyboard interaction |
| Active / Pressed | Deeper translucent state layer | |
| Disabled | fgColor-disabled opacity | Consider Inactive state instead of Disabled — disabled buttons can frustrate users |
| Loading | Spinner replaces label; button disabled | Apply aria-disabled="true"; keep button focusable; use hidden live region for status |
| Inactive | Muted styling; responds to input | Use aria-disabled="true" only if the button is non-interactive |
Best practices
- Label: Keep labels short and use sentence case. No line breaks. Labels should describe the action clearly enough to stand alone.
- Primary button: Use only one primary button per page or button group, and typically only one per view.
- Pairing: Primary buttons should be paired with secondary buttons, not other primary buttons.
- Position: Place the primary button at the end of a button group (right side in LTR layouts).
- Icons: Leading icons provide context but don't replace label text. Don't rely on an icon alone to convey meaning.
- Selecting multiple items: Use "2 selected" format rather than comma-separated value lists on the button label.
Accessibility
- Minimum touch target: 24×24 CSS pixels.
- Accessible name: The button label is the accessible name. It must be descriptive enough on its own — don't rely on surrounding context or icons.
- Focus indicator: Always display focus styles on keyboard interaction. Do not suppress the focus ring.
- Icons: Octicons used as leading/trailing visuals are purely visual — no text alternative is provided. Screen readers hear only the button label.
- Disabled vs. Inactive:
- Prefer Inactive state over Disabled. Disabled buttons are not focusable in some implementations, reducing discoverability.
- An Inactive button that shows a dialog on click should not use
aria-disabled. - An Inactive button that is truly non-interactive may use
aria-disabled="true".
- Loading state: Apply
aria-disabled="true", keep the button focusable, and use a visually hidden live region to communicate loading status to screen reader users. - ARIA role: Native
<button>element. Use role="button" only when a non-button element must be interactive — prefer the native element. - Keyboard interaction:
Tab/Shift+Tab: Move focus to/from buttonEnterorSpace: Activate button