Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
A “button group” in Vanilla Breeze is not a new component — it is whichever of menu.toolbar, menu.pills, or layout-cluster fits the job. This page is the signpost.
Before reaching for a custom element, match the interaction to the pattern already shipped:
| What you need | Use | Why |
|---|---|---|
| Action bar in a panel or card header (bold, copy, link, …) | menu.toolbar |
Groups icon/text buttons with a rounded track, single focus-ring style, and role="toolbar" via the native <menu> element. |
| Filter or category chips (“All”, “Open”, “Closed”) | menu.pills |
Pill-shaped buttons with chip spacing. Pair with aria-pressed for sticky selections. |
| Form or dialog footer buttons (Cancel / Save) | <layout-cluster> |
Wrapping flex row with consistent gap and end-justified alignment. Not semantically a toolbar. |
| Mutually exclusive options with radio semantics | data-segmented |
CSS-only segmented control over native radio inputs. Proper form submission and arrow-key nav. |
Use menu.toolbar for grouped action buttons. The native <menu> element already means “group of commands,” so you get the right semantics without extra roles.
<menu class="toolbar" aria-label="Formatting"> <li><button type="button" aria-label="Bold"><icon-wc name="bold"></icon-wc></button></li> <li><button type="button" aria-label="Italic"><icon-wc name="italic"></icon-wc></button></li> <li><button type="button" aria-label="Underline"><icon-wc name="underline"></icon-wc></button></li> <li role="separator"></li> <li><button type="button" aria-label="Insert link"><icon-wc name="link"></icon-wc></button></li></menu>
For a sticky multi-select toolbar — where several options can be on at once — use aria-pressed on each button. The attribute exposes the pressed state to assistive tech and lets you style both states with a single rule: button[aria-pressed="true"].
For mutually exclusive selection (one must be on, all others off), use data-segmented over native radio inputs instead — that is what radios are for.
<menu class="toolbar" aria-label="Text alignment"> <li><button type="button" aria-pressed="true" aria-label="Bold"><icon-wc name="bold"></icon-wc></button></li> <li><button type="button" aria-pressed="false" aria-label="Italic"><icon-wc name="italic"></icon-wc></button></li> <li><button type="button" aria-pressed="false" aria-label="Underline"><icon-wc name="underline"></icon-wc></button></li></menu> <script> document.querySelectorAll('menu.toolbar button[aria-pressed]').forEach(btn => { btn.addEventListener('click', () => { btn.setAttribute('aria-pressed', btn.getAttribute('aria-pressed') === 'true' ? 'false' : 'true'); }); });</script>
Styling pressed state. Add this alongside your toolbar CSS:
menu.toolbar button[aria-pressed="true"] { background: var(--color-surface-active); color: var(--color-text-strong); box-shadow: inset 0 1px 2px oklch(0% 0 0 / 0.1);}
For rounded chip-style groups — filters, tag selectors, view switchers — use menu.pills. Same semantics as the toolbar, different shape.
<menu class="pills" aria-label="Status filter"> <li><button type="button" aria-pressed="true">All</button></li> <li><button type="button" aria-pressed="false">Open</button></li> <li><button type="button" aria-pressed="false">Closed</button></li></menu>
For modal/dialog/form footers, reach for <layout-cluster>. It is not a toolbar — just a wrapping flex row with consistent gap and end-justified alignment.
<footer> <layout-cluster data-layout-justify="flex-end" data-layout-gap="s"> <button type="button" class="secondary">Cancel</button> <button type="submit" class="primary">Save</button> </layout-cluster></footer>
data-segmented for the segmented-control look.Full reference for menu.toolbar, .pills, .icons, and .vertical.
Segmented control over native radios for mutually-exclusive selection.
Overflow or secondary actions behind a trigger.