A button group places related buttons in one visual cluster. Use it for commands such as playback controls or for toggle buttons such as text formatting. Each item remains a native button and a Tab stop.
The root is a <div class="button-group">. Common
buttons and
icon buttons can be direct children.
Expressive.AutoInit() keeps standard-group width stable while
the pressed item grows; data-selection additionally enables
managed toggle state.
<div class="button-group" data-selection="multiple"
role="group" aria-label="Text formatting">
<button type="button" class="button tonal" aria-pressed="false">
<span class="material-symbols" aria-hidden="true">format_bold</span>
Bold
</button>
<button type="button" class="button tonal" aria-pressed="false">
<span class="material-symbols" aria-hidden="true">format_italic</span>
Italic
</button>
<button type="button" class="button tonal" aria-pressed="false">
<span class="material-symbols" aria-hidden="true">format_underlined</span>
Underline
</button>
</div>
Use a plain group for commands. Add selection behavior only when pressing a button toggles an on/off state. Use a segmented button when two to five choices form a compact form field whose value belongs in radios or checkboxes.
Standard
Standard is the default. Items keep separate shapes, and the gap closes
as the size grows: 18dp at xsmall, 12dp at
small, and 8dp from medium through
xlarge. Pressing an item widens it by 15% of its measured
width and morphs its corners toward the square shape for that size. The
immediate neighbors provide the width, so the group's outer width stays
fixed.
<div class="button-group" role="group" aria-label="Playback">
<button type="button" class="icon-button filled" aria-label="Previous track">
<span class="material-symbols" aria-hidden="true">skip_previous</span>
</button>
<button type="button" class="icon-button filled" aria-label="Play">
<span class="material-symbols" aria-hidden="true">play_arrow</span>
</button>
<button type="button" class="icon-button filled" aria-label="Next track">
<span class="material-symbols" aria-hidden="true">skip_next</span>
</button>
</div>
Connected
Add connected to a selection group; do not use the connected
treatment for one-shot actions. The group fills its container with equal
items separated by 2dp. The outer ends remain round while the joins are
squared off. The live M3 measurement keeps the xsmall join
at 4dp; pressing small and medium changes their
inner corners from 8dp to 4dp. The larger pairs are 16dp to 12dp at
large and 20dp to 16dp at xlarge.
<div class="button-group connected"
data-selection="single"
data-selection-required
role="group"
aria-label="Text alignment">
<button type="button" class="icon-button tonal"
aria-label="Align left" aria-pressed="true">
<span class="material-symbols" aria-hidden="true">format_align_left</span>
</button>
<button type="button" class="icon-button tonal"
aria-label="Align center" aria-pressed="false">
<span class="material-symbols" aria-hidden="true">format_align_center</span>
</button>
<button type="button" class="icon-button tonal"
aria-label="Align right" aria-pressed="false">
<span class="material-symbols" aria-hidden="true">format_align_right</span>
</button>
</div>
Selection
A selection group contains toggle buttons. Add
data-selection="single" when at most one item may be on, or
data-selection="multiple" for independent toggles. Add
data-selection-required when at least one must remain on.
Give every item its initial aria-pressed value;
ButtonGroup maintains it after AutoInit().
<div class="button-group connected"
data-selection="multiple"
role="group"
aria-label="Text formatting">
<button type="button" class="button filled" aria-pressed="true">Bold</button>
<button type="button" class="button filled" aria-pressed="false">Italic</button>
<button type="button" class="button filled" aria-pressed="false">Underline</button>
</div>
<script>
Expressive.AutoInit();
</script>
Selection changes color, shape, and icon fill, so color is not the only
cue. Native buttons provide Enter and Space activation; all items remain
in the Tab order. Keep visible labels when space allows. Give an unfamiliar
icon-only item a tooltip as well as an aria-label.
Sizes
Put xsmall, small (the default),
medium, large, or xlarge on the
group. Common and icon buttons inherit the matching 32dp, 40dp, 56dp,
96dp, or 136dp geometry. An explicit size on a child still wins. The
32dp and 40dp visual sizes keep a minimum 48dp interaction target.
<div class="button-group medium">
<button type="button" class="button tonal">One</button>
<button type="button" class="button tonal">Two</button>
<button type="button" class="button tonal">Three</button>
</div>
Semantics
A button group is not a composite widget. Do not use
role="toolbar", radiogroup, or a roving
tabindex: items are reached with Tab. When the cluster needs
a name, use role="group" with aria-label or
aria-labelledby. This role adds no arrow-key contract.
Action groups accept a direct <button> or
<a class="button" href>. Selection groups accept only
direct <button type="button"> items, each with an
initial aria-pressed. Links cannot expose toggle state. The
native button supplies keyboard activation, and ButtonGroup
changes the state on the resulting click.
Give every icon-only item an accessible name because its decorative icon
is aria-hidden. Avoid a standard icon button when its meaning
is not familiar; use a filled, tonal, or outlined container and a tooltip.
Reduced-motion preferences remove the width and shape transitions.
Tokens
Set these properties on the group. The defaults describe a small standard group; size and variant classes replace the values that differ.
| Token | Default |
|---|---|
--md-comp-button-group-between-space | 12px |
--md-comp-button-group-pressed-item-width-multiplier | .15 |
--md-comp-button-group-item-shape-round | 9999px |
--md-comp-button-group-item-shape-square | 12px |
--md-comp-button-group-pressed-item-shape | 8px |
--md-comp-button-group-container-shape | 9999px (connected) |
--md-comp-button-group-inner-corner-corner-size | 8px (connected) |
--md-comp-button-group-pressed-inner-corner-corner-size | 4px (connected) |
--md-comp-button-group-selected-inner-corner-corner-size | 50% (connected) |
Child geometry and colors still come from the button or icon-button token
family. Toggle groups map the selected and unselected Material button
colors onto aria-pressed and retain hover, focus, pressed,
disabled, and focus-ring feedback.