ButtonGroup

ButtonGroup renders a series of buttons.

Page navigation navigation

A ButtonGroup does not behave like a toolbar, so assistive technologies still interpret the buttons as unrelated. The grouping is purely visual.

As toolbar

By default, a button group does not behave like a toolbar, so assistive technologies still interpret the buttons as unrelated. The grouping is purely visual.

If you want to make the button group behave like a toolbar, you can add the role="toolbar" prop to the ButtonGroup component. This will communicate the appropriate role to assistive technologies.

When role="toolbar" is used, individual buttons aren't separately focusable. Instead, only one button receives focus, and users switch between all buttons in the toolbar using the cursor keys. This behavior is baked into the component.

Please note the toolbar keyboard interaction behaviors are currently implemented in Primer React only, and are not available in Primer View Components.

Descriptive buttons

Labeling buttons properly lets users know what will happen when they activate the control, lessens errors, and increases confidence.

Read more about descriptive buttons.

Accessibility and usability expectations

Cognition

  • Each button within the button group has a clear and succinct label that informs users as to the purpose of the control
  • When icon-only buttons are used within the button group, ensure they have a clear accessible name that conveys equivalent information

Vision

  • Ensure a visible label text meets the minimum contrast requirement of 4.5:1
  • If the visible label is represented by an icon, ensure the icon has a 3:1 contrast ratio against the background

Mobility

  • Buttons within the button group must have a minimum target size of 24×24 CSS pixels. This is to ensure that the button is large enough to be easily activated by users with motor impairments

Adaptability

  • The button labels should remain legible when resized up to 200%
  • When zoomed to 400% or viewed at a width of 320px, content and functionality must remain fully available without horizontal scrolling
  • When adding additional text spacing, make sure that visible labels can still be read in their entirety

Interaction

Keyboard

  • Each button must receive focus when navigating with the Tab key
  • Enter or Space must select the button
  • Buttons must receive focus in a logical order, which in the majority of cases, will be the order that they are visually displayed
  • When role="toolbar" is used, individual buttons aren't separately focusable. Instead, only one button receives focus, and users switch between all buttons in the toolbar using the cursor keys. This behaviour is baked into the component
  • For a split button with a dropdown, ensure that when the dropdown is triggered, focus moves to the first item in the list. After an option is selected, focus should return to the button that originally triggered the dropdown

Touch and mouse

  • Buttons must be activated on the up event, and not the down event, or there must be a way to prevent the action from taking place on the down event

Engineering for Assistive Technology (AT) compatibility

Screen reader support

  • A button group does not behave like a toolbar, so assistive technologies still interpret the buttons as unrelated. The grouping is purely visual
  • If you want to make the button group behave like a toolbar, you can add the role="toolbar" to the ButtonGroup component. This will communicate the appropriate role to assistive technologies, additionally, provide an accessible name to the toolbar by adding an aria-label with an appropriate value

Speech recognition

  • The buttons should have an accessible name that matches or includes the visible label

Built-in accessibility features

  • For the split button with a dropdown that reveals an additional list of actions, the button element containing the downward-facing chevron should include aria-haspopup="true" to indicate the presence of a submenu, along with aria-expanded to reflect the current state of the dropdown (i.e., true when open, false when closed)
  • The dropdown's list of actions should be structured using <li> elements within a <ul> that has role="menu", with each individual action assigned role="menuitem"

Implementation requirements

  • If the button group is intended to function as a toolbar, the wrapping <div> should include role="toolbar" to ensure that assistive technologies recognize and communicate the grouping of controls appropriately
  • Additionally, provide the toolbar with an accessible name using the aria-label attribute to convey its purpose to screen reader users
  • Ensure that all buttons are clearly labelled to communicate their purpose and expected outcome. This helps reduce user errors and increases confidence in using the interface

How to test the component

Integration tests

  • Ensure each button has an accessible name
  • Ensure the component reflows correctly when zoomed or resized

Component tests

  • Verify that if the button group is intended as a toolbar, there is a role="toolbar" on the div that wraps around the buttons, additionally, ensure there is an accessible name provided to this toolbar, this can be via an aria-label
  • In the case of the split button with a dropdown, ensure the correct ARIA attributes are applied to the button that triggers the list: aria-haspopup="true", and aria-expanded with a value of true when the list is expanded, and false when it is collapsed