Checkbox Group
CheckboxGroup is a headless fieldset container that groups related checkboxes under the ARIA group role. It manages a collection of checkboxes with shared state, supporting a "Select all" checkbox with automatic indeterminate state, group-level disabled state, and two-way binding of selected values.
Use CheckboxGroup when you need multiple checkboxes that share a logical relationship, such as selecting features, choosing categories, or picking multiple items from a list. The component wraps native checkbox inputs in a <fieldset> element, ensuring proper semantic grouping and accessibility without imposing any visual styling.
Implementation Notes
- Renders a
<fieldset>element withrole="group"for explicit ARIA semantics - The
aria-labelattribute on the fieldset provides an accessible name for the group - Consumer provides checkbox children (typically
<label>elements wrapping<input type="checkbox">) - Spreads
restPropsonto the fieldset for consumer customization - No internal state management; checkbox selection is handled by native checkbox behavior
- Supports a "Select all" pattern where the consumer can add a checkbox that toggles all options, with automatic indeterminate state when some but not all options are selected
Props
label: string (required) -- accessible label for the checkbox group, applied viaaria-labelchildren: slot (required) -- checkbox elements to render inside the fieldsetdisabled: boolean (default: false) -- disables the entire group via the fieldsetdisabledattribute...restProps: unknown -- additional attributes spread onto the<fieldset>element
Usage
<Fieldset legend="How would you like to be contacted?">
<Hint>Select all that apply</Hint>
<CheckboxGroup name="contact-methods">
<CheckboxInput label="Email" value="email" />
<CheckboxInput label="Phone" value="phone" />
<CheckboxInput label="Text message" value="sms" />
</CheckboxGroup>
</Fieldset>
<CheckboxGroup label="Toppings" disabled>
<CheckboxInput label="Cheese" name="toppings" value="cheese" />
<CheckboxInput label="Peppers" name="toppings" value="peppers" />
</CheckboxGroup>
Keyboard Interactions
- Tab: Moves focus between checkboxes within the group (native browser behavior)
- Space: Toggles the focused checkbox checked state (native browser behavior)
ARIA
role="group"-- identifies the fieldset as a group of related checkboxesaria-label={label}-- provides an accessible name for the group so screen readers announce the purpose- Native
<fieldset>disabledattribute propagates disabled state to all child inputs
When to Use
- Use to wrap multiple CheckboxInput components that share a common name and manage collective state
- Use within a Fieldset so the group has a descriptive legend for accessibility
- Use when the form needs to track which checkboxes are selected as a set
When Not to Use
- Do not use for a single standalone checkbox — render CheckboxInput directly
- Do not use when only one option can be selected — use RadioGroup with RadioInput instead
- Do not use for visual-only grouping without shared state — use a Fieldset alone
Headless
The CheckboxGroup headless component provides a <fieldset> with role="group", aria-label, and an optional disabled attribute for group-level disabling. It relies on native checkbox behavior for selection and keyboard navigation. The consumer provides all visual styling for the fieldset, labels, checkboxes, and indeterminate state indicators.
Styles
The consumer provides all CSS styling. The component renders with a .checkbox-group class for targeting. Common styling concerns include layout (vertical vs. horizontal stacking), spacing between items, disabled opacity, and custom checkbox indicators.
Testing
- Verify the component renders a
<fieldset>element withrole="group" - Verify
aria-labelis set from thelabelprop - Verify child checkbox inputs render inside the fieldset
- Verify the
disabledattribute propagates to child inputs when set on the group - Verify pass-through attributes are applied to the fieldset
Advice
- Designers: Stack checkbox options vertically for readability. Provide clear labels and ensure adequate spacing between items. When using "Select all," place it visually before the individual options and use an indeterminate indicator when only some items are selected.
- Developers: Use the native
<fieldset>disabledattribute for group-level disabling. For "Select all" behavior, manage the indeterminate state in your application logic by comparing the number of selected items to the total. Ensure all checkboxes within the group share the samenameattribute for proper form submission.
Composition
CheckboxGroup is the container for CheckboxInput children. Use <CheckboxGroup> to wrap multiple <CheckboxInput> elements or native <input type="checkbox"> elements, providing the group-level accessible label and optional disabled state while each checkbox carries its own option label.
Related components
checkbox-input— a checkbox input for toggling a boolean value <input type="checkbox">radio-group— a group of radio buttons for selecting one optiontoggle-group— a group of toggle buttons for selecting options
References
- WAI-ARIA Checkbox Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/
- WAI-ARIA Group Role: https://www.w3.org/TR/wai-aria-1.2/#group
- WAI-ARIA Authoring Practices - Checkbox: https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/