Skip to content

Button

Primary action — the site’s black button.

Beta · Actions · packages/css/src/components/button.css · React on Base UI: @pepperui/button

.pui-button · variant --secondary --ghost --danger · size --small --large · __icon · --block. States: :hover :focus-visible :active :disabled.

Button — every size and every stateOpen in the workshop

Sizes across, states down.

  • Optional leading and trailing icons, off by default
  • Three sizes: small, medium, large — medium is the site’s real one
  • Five states: default, hover, focus, pressed, disabled
  • Secondary and ghost are separate component sets
  • Beside inputs or selects — the end of a filter row, a form’s inline action — the button is THIS one, the black default: an outlined secondary next to outlined controls reads as one more control

Use when the one action a view exists for — submit, save, create.

Do not use when two actions compete (one primary per view, principle 1); for navigation (that is a link); for on/off (that is Toggle).

Relates to Button - secondary, Button - ghost, Button - danger, Icon button, Button group, Icon.

Anti-patterns two primary buttons side by side · a primary button for cancel · ALL CAPS labels · a pill-shaped button (labels are pills, actions are squares) · a fill changed on the instance.

Keywords: action, primary, submit, cta, button

Figma — page Button: Button (15 variants) · Button - secondary (15 variants) · Button - ghost (15 variants) · Button - danger (15 variants)

shadcn: button

The class, the parts, and nothing that is not in the package. The same block opens button.css.

<button class="pui-button">Save</button>
<button class="pui-button pui-button--secondary pui-button--small">
<span class="pui-icon pui-button__icon">…lucide svg…</span>Back</button>
<a class="pui-button pui-button--ghost" href="…">Skip</a>
What it is Note
Variant (none) primary · --secondary · --ghost · --danger the four Figma sets; the registry’s variant
Size --small 28 · (none) medium 36 · --large 44 size/control/*; font 12 / 14 / 16
State :hover · :focus-visible · :active · :disabled, [aria-disabled=“true”] —
Parts __icon — a 16 px glyph before or after the label (Has icon leading / trailing) —
Extra --block — width 100 % —

Rule — beside inputs or selects (the end of a filter row, a form’s inline action) the button is the black one, never the outlined secondary — an outline next to outlined controls reads as one more control.

Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.

ink on ground reads floor the matrix calls it
#ffffff on #e42521 4.57 4.5 Danger button label (promised) ok
#544d4d on #ffffff 8.24 4.5 text.muted on surface.page (promised) ok
#0b0202 on #f2f2f7 18.38 4.5 text.default on surface.card (promised) ok
#0b0202 on #ffffff 20.51 4.5 text.default on surface.page (promised) ok
#ffffff on #0b0202 20.51 4.5 Primary button label (promised) ok

5 distinct pair(s) rendered, 0 that axe calls a violation.

primitive on the indicator over the change
Button surface/page shadow #6a66e4 2 px #ffffff 4.53 ok
Button surface/card shadow #6a66e4 2 px #f2f2f7 4.06 ok
Button surface/sunken shadow #6a66e4 2 px #f2f2f2 4.05 ok
Button - secondary surface/page shadow #6a66e4 2 px #ffffff 4.53 ok
Button - secondary surface/card shadow #6a66e4 2 px #f2f2f7 4.06 ok
Button - secondary surface/sunken shadow #6a66e4 2 px #f2f2f2 4.05 ok
Button - ghost surface/page shadow #6a66e4 2 px #ffffff 4.53 ok
Button - ghost surface/card shadow #6a66e4 2 px #f2f2f7 4.06 ok
Button - ghost surface/sunken shadow #6a66e4 2 px #f2f2f2 4.05 ok
Icon button surface/page shadow #6a66e4 2 px #ffffff 4.53 ok
Icon button surface/card shadow #6a66e4 2 px #f2f2f7 4.06 ok
Icon button surface/sunken shadow #6a66e4 2 px #f2f2f2 4.05 ok

20 of 20 focus stop(s) in this block meet WCAG 2.4.13 on screen — the same crop screenshotted focused and unfocused, and the difference measured.

Nothing in this component claims an ARIA role with a keyboard contract; its controls are ordinary ones and the browser already gives them their keys.

Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).

Pepper UI v1.5.0

The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.