Snippets / UI Components /

Split Button

A split button with a primary action and a dropdown arrow — two clickable zones separated by a vertical divider.

Widely Supported
ui

Quick implementation

.split-button-demo {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius);
  overflow: hidden;
  font-family: var(--font-sans);
}
.split-button-demo__main {
  flex: 1;
  padding: 0.5rem 1rem;
  background: oklch(0.6 0.15 250);
  color: oklch(1 0 0);
  border: none;
  cursor: pointer;
  text-align: left;
}
.split-button-demo__divider {
  width: 1px;
  background: oklch(1 0 0 / 0.3);
  height: 60%;
}
.split-button-demo__arrow {
  padding: 0.5rem 0.75rem;
  background: oklch(0.6 0.15 250);
  color: oklch(1 0 0);
  border: none;
  cursor: pointer;
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer building a design system component library.

Goal: A split button — a primary action button joined to a dropdown-trigger arrow, separated by a vertical divider, that opens a menu on arrow click.

Technical constraints:
- Use flexbox on the container; overflow: hidden clips children to the shared border-radius.
- Use oklch() for all colors — no hex or rgba().
- Both the main button and arrow button must be separate <button> elements, each individually focusable.
- Arrow button needs aria-label="More options", aria-expanded, and aria-haspopup="menu".
- The dropdown menu toggles via a .is-open class on the container — JS adds/removes it on arrow click.

Framework variant (pick one):
A) Vanilla HTML + CSS + minimal JS — toggle .is-open on the wrapper, close on outside click.
B) React component — accept label, onClick, and menuItems (array of { label, onClick }) props.

Edge cases to handle:
- Close dropdown on Escape key and on click outside.
- Disabled state for the entire component: both buttons get disabled attribute.
- Dropdown positioning: use position: absolute so it doesn't shift surrounding layout.

Return HTML + CSS + JS (or TSX + CSS module for React).

Why this matters in 2026

Split buttons reduce interface clutter by grouping a primary action and its variants into a single visual unit. The CSS covers the layout and styling — the dropdown menu that opens when you click the arrow requires a small JavaScript toggle. This snippet gives you the hard part: the two-zone component that looks and feels right.

The logic

display: inline-flex on the container aligns the main button and arrow button side by side. overflow: hidden clips both children to the container's border-radius, giving a unified pill shape. A thin <span> with a semi-transparent background acts as the divider between zones — no border juggling needed.

Accessibility & performance

Both buttons must be separately focusable and tabbable — never wrap them in a single <button>. The arrow button should have an explicit aria-label="More options" since "▼" alone is meaningless to a screen reader. When you wire up the JS dropdown, add aria-expanded on the arrow button and aria-haspopup="menu" to communicate the pattern correctly.