Split Button
A split button with a primary action and a dropdown arrow — two clickable zones separated by a vertical divider.
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.