Browse Components

Button Group

Connect related actions in a single visual group.

Basic

Related links share a connected outline. Each link opens its component page.

View Code
HTML
<div class="button-group" role="group" aria-label="Form components">
  <a class="btn secondary" href="/components/input">
    Input
  </a>
  <a class="btn secondary" href="/components/select">
    Select
  </a>
  <a class="btn secondary" href="/components/number">
    Number
  </a>
</div>

Icons and text

Shared icons align with button labels. These links navigate between component pages.

View Code
HTML
<div class="button-group" role="group" aria-label="Component navigation">
  <a
    class="btn secondary"
    href="/components/button"
    aria-label="Back to Button component"
  >
    <svg
      class="icon"
      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="m15 5-7 7 7 7">
      </path>
    </svg>
    <span>
      Back
    </span>
  </a>
  <a class="btn secondary" href="/components" aria-label="Home: all components">
    <svg
      class="icon"
      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="m3 10 7.8-6.1a2 2 0 0 1 2.4 0L21 10M5 9v10a2 2 0 0 0 2 2h3v-6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v6h3a2 2 0 0 0 2-2V9">
      </path>
    </svg>
    <span>
      Home
    </span>
  </a>
  <a class="btn secondary" href="/components/card" aria-label="Next component: Card">
    <span>
      Next
    </span>
    <svg
      class="icon"
      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="m9 5 7 7-7 7">
      </path>
    </svg>
  </a>
</div>

Icon only

Use btn-icon for equal square controls and accessible names for every icon-only link.

View Code
HTML
<div class="button-group" role="group" aria-label="Component navigation">
  <a
    class="btn secondary btn-icon"
    href="/components/button"
    aria-label="Back to Button component"
  >
    <svg
      class="icon"
      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="m15 5-7 7 7 7">
      </path>
    </svg>
  </a>
  <a class="btn secondary btn-icon" href="/components" aria-label="Home: all components">
    <svg
      class="icon"
      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="m3 10 7.8-6.1a2 2 0 0 1 2.4 0L21 10M5 9v10a2 2 0 0 0 2 2h3v-6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v6h3a2 2 0 0 0 2-2V9">
      </path>
    </svg>
  </a>
  <a
    class="btn secondary btn-icon"
    href="/components/card"
    aria-label="Next component: Card"
  >
    <svg
      class="icon"
      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="m9 5 7 7-7 7">
      </path>
    </svg>
  </a>
</div>

Feedback with counts

Try a thumbs-up or thumbs-down vote. Counts update locally; click again to undo your vote.

View Code
HTML
<div class="button-group" role="group" aria-label="Was this helpful?" data-vote-demo>
  <button
    class="btn secondary"
    type="button"
    aria-pressed="false"
    aria-label="Helpful"
    data-vote="128"
  >
    <svg
      class="icon"
      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"
    >
      <rect x="3" y="10" width="4" height="11" rx="1">
      </rect>
      <path d="M7 10l5-7c2 0 3 2 2 5l-.5 2H19a2 2 0 0 1 2 2l-1 7a2 2 0 0 1-2 2H9l-2-2Z">
      </path>
    </svg>
    <span data-vote-count>
      128
    </span>
  </button>
  <button
    class="btn secondary"
    type="button"
    aria-pressed="false"
    aria-label="Not helpful"
    data-vote="8"
  >
    <svg
      class="icon"
      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"
    >
      <rect x="3" y="3" width="4" height="11" rx="1">
      </rect>
      <path d="M7 14l5 7c2 0 3-2 2-5l-.5-2H19a2 2 0 0 0 2-2l-1-7a2 2 0 0 0-2-2H9L7 5Z">
      </path>
    </svg>
    <span data-vote-count>
      8
    </span>
  </button>
</div>

Sizes

Apply one shared button size to every member. Small targets expand on touch devices.

View Code
HTML
<div class="stack">
  <div class="button-group" role="group" aria-label="Small form components">
    <a class="btn secondary btn-small" href="/components/input">
      Input
    </a>
    <a class="btn secondary btn-small" href="/components/select">
      Select
    </a>
    <a class="btn secondary btn-small" href="/components/number">
      Number
    </a>
  </div>
  <div class="button-group" role="group" aria-label="Form components">
    <a class="btn secondary" href="/components/input">
      Input
    </a>
    <a class="btn secondary" href="/components/select">
      Select
    </a>
    <a class="btn secondary" href="/components/number">
      Number
    </a>
  </div>
  <div class="button-group" role="group" aria-label="Large form components">
    <a class="btn secondary btn-large" href="/components/input">
      Input
    </a>
    <a class="btn secondary btn-large" href="/components/select">
      Select
    </a>
    <a class="btn secondary btn-large" href="/components/number">
      Number
    </a>
  </div>
</div>

Mixed emphasis

Give the main destination more emphasis while keeping related links together.

View Code
HTML
<div class="button-group" role="group" aria-label="Form components">
  <a class="btn" href="/components/input">
    Input
  </a>
  <a class="btn secondary" href="/components/select">
    Select
  </a>
  <a class="btn secondary" href="/components/number">
    Number
  </a>
</div>

Vertical

Stack longer groups vertically without broken seams.

View Code
HTML
<div class="button-group button-group-vertical" role="group" aria-label="Form components">
  <a class="btn secondary" href="/components/input">
    Input
  </a>
  <a class="btn secondary" href="/components/select">
    Select
  </a>
  <a class="btn secondary" href="/components/number">
    Number
  </a>
</div>

Full width

Distribute related destinations across the available width.

View Code
HTML
<div class="button-group button-group-full" role="group" aria-label="Form components">
  <a class="btn secondary" href="/components/input">
    Input
  </a>
  <a class="btn secondary" href="/components/select">
    Select
  </a>
  <a class="btn secondary" href="/components/number">
    Number
  </a>
</div>

Disabled action

Unavailable actions retain their place and are skipped by keyboard navigation. The edit link opens the Input component.

Edit
View Code
HTML
<div class="button-group" role="group" aria-label="Draft actions">
  <a class="btn secondary" href="/components/input">
    Edit
  </a>
  <button class="btn secondary" type="button" disabled>
    Publish
  </button>
</div>

Right to left

Connected corners follow the reading direction.

View Code
HTML
<div class="button-group" role="group" dir="rtl" lang="he" aria-label="רכיבי טופס">
  <a class="btn secondary" href="/components/input">
    קלט
  </a>
  <a class="btn secondary" href="/components/select">
    בחירה
  </a>
  <a class="btn secondary" href="/components/number">
    מספר
  </a>
</div>

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">
<link rel="stylesheet" href="/library/assets/button-group.css">

12,548 bytes CSS including base · 0 bytes runtime JavaScript

Usage

Interactive examples

Feedback counts use local demo JavaScript, not a server. The split download example uses the native Popover API with popup and menu for the popup, positioning and keyboard behavior. Copy the feedback demo behavior when adapting its counts; Button Group itself remains CSS-only.

Group related actions

Use role=group with aria-label or aria-labelledby. Direct children use the shared btn styles. Choose buttons for actions and real links for navigation. Each control keeps normal Tab and Enter or Space behavior. This is not a selection widget; use Segmented for a single chosen value.

Size and direction

Use the same button size for all members. Add button-group-vertical for a column or button-group-full to fill available width. Groups use theme corners and logical edges for RTL. Keep horizontal labels short; use vertical groups for longer labels on small screens.

States

Native disabled buttons cannot activate and are skipped by Tab. Keep an accessible name on icon-only buttons. Focus rings stay visible above neighboring buttons. No JavaScript or automatic actions are supplied.

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