Checkbox
The <Checkbox>
component is a form element that allows users to make a binary choice, either selecting or deselecting an option. Multiple checkboxes can be grouped together using <Checkbox.Group>
to enable the selection of zero, one or any number of options.
It is commonly used in forms, settings, and anywhere users need to make multiple selections or toggle individual options. A <Checkbox>
can also display an indeterminate state to represent a partially selected group.
Anatomy
A checkbox consists of a clickable box and a label. The box has three states: unchecked, checked, or indeterminate. The label, positioned next to the checkbox, describes the option or action associated with it. Users interact with the checkbox by clicking the box or label to toggle between states.
A checkbox group consists of multiple checkboxes, each with its own label, allowing users to select one or more options within a related set.

Appearance
The appearance of a component can be customized using the variant
and size
props. These props adjust the visual style and dimensions of the component, available values are based on the active theme.
Property | Type | Description |
---|---|---|
variant | - | The available variants of this component. |
size | - | The available sizes of this component. |
Usage
Checkboxes are used when there are multiple items to select in a list. Each checkbox works independently from other checkboxes in the list, therefore checking an additional box does not affect any other selections. Users can select zero, one, or any number of items. Checkboxes are commonly used in forms where users need to make multiple selections from a set of options.
Particularly checkboxes are useful in settings where users need to make non-exclusive selections. They provide a clear and straightforward way to toggle options on or off. When used in a group, they can help simplify complex decision-making processes. Additionally, checkboxes can be combined with other form elements.
Labeling
We recommend checkbox labels being fewer than three words because shorter checkbox labels improve readability and reduce cognitive load, making it easier for users to quickly understand and select options. This enhances the overall user experience, especially on small screens.
If you are tight on space, consider rewording the label. Do not truncate checkbox label text with an ellipsis. Long labels may wrap to a second line, and this is preferable to truncation.

If the label is long, wrap to a second line.

Do not truncate checkbox label text with an ellipsis.
Number of options
Use checkboxes when there are no more than 10 to 15 options, as too many of them can overwhelm users and clutter the interface. For larger sets of options, refer to the Multiple Selection Pattern for a better user experience.
If a user can select only one option from a list, radio buttons should be used instead, as checkboxes suggest that multiple options can be chosen.

Use checkboxes when you have up to 15 options, and multiple options can be chosen.

Don't use checkboxes when only one item can be selected.
When a checkbox list is long enough to create clutter, overload, or excessive scrolling, keep it compact while allowing access to all options. Show only the most relevant five to eight items initially, with the rest hidden until revealed, and use this approach sparingly when all items can be scanned easily. Use this method sparingly, avoiding its use when the total number of items can be quickly scanned without frustration.
If the selected value is within the collapsed section, the component renders in its expanded state by default.
Ordering of Options
Options should be arranged by relevance to help users find what they need quickly. Prioritizing by factors such as frequency of use, overall popularity, or recency of interaction ensures the most useful items appear first. Alphabetical order should be considered only when no meaningful ranking criteria are available, as it may not align with user priorities or usage patterns.
Checkbox or switch
Use a checkbox when its effect will only occur after the user submits or confirms the selection. Checkboxes are ideal for allowing users to choose options that need to be finalized through submission, such as in a form.
In contrast, use a switch for actions that take effect immediately upon toggling, without requiring further confirmation or submission, making switches more suitable for instant settings changes.

Use checkboxes in forms where the selection will only take effect upon submission.

Don't use a checkbox to toggle a state with immediate effect.
Indeterminate
The indeterminate state of a checkbox is used when a group of related checkboxes is partially selected, meaning some but not all options are chosen. This state visually indicates that the selection is incomplete or mixed.
It’s commonly used in "Select All" scenarios, where selecting only some of the available options triggers the parent checkbox to show an indeterminate state, helping users understand that not all choices have been selected.
Description
Adding a description to a checkbox is helpful when the label alone isn't enough to explain its function. Use a description to clarify complex or ambiguous actions, such as when the checkbox triggers a permanent change or has significant consequences. It's also useful for explaining technical terms or jargon that might be unfamiliar to the user. Finally, include a description to provide important context or warnings, like legal disclaimers or potential costs, ensuring the user fully understands what they're agreeing to.
Props
Checkbox
aria-controls?
string;
aria-describedby?
string;
aria-details?
string;
aria-errormessage?
string;
aria-label?
string;
aria-labelledby?
string;
autoFocus?
boolean;
checked?
boolean;
defaultChecked?
boolean;
description?
ReactNode;
dir?
string;
disabled?
boolean;
"false"
error?
boolean;
true
, the checkbox is considered invalid and if set the errorMessage
is shown instead of the description
."false"
excludeFromTabOrder?
boolean;
form?
string;
<form>
element to associate the input with.
The value of this attribute must be the id of a <form>
in the same document.
See MDN.hidden?
boolean;
id?
string;
indeterminate?
boolean;
"false"
inert?
boolean;
inputRef?
RefObject<HTMLInputElement | null>;
label?
ReactNode;
"none"
lang?
string;
name?
string;
onAnimationEnd?
AnimationEventHandler<HTMLLabelElement>;
onAnimationEndCapture?
AnimationEventHandler<HTMLLabelElement>;
onAnimationIteration?
AnimationEventHandler<HTMLLabelElement>;
onAnimationIterationCapture?
AnimationEventHandler<HTMLLabelElement>;
onAnimationStart?
AnimationEventHandler<HTMLLabelElement>;
onAnimationStartCapture?
AnimationEventHandler<HTMLLabelElement>;
onAuxClick?
MouseEventHandler<HTMLLabelElement>;
onAuxClickCapture?
MouseEventHandler<HTMLLabelElement>;
onBlur?
(e: FocusEvent<Element, Element>) => void;
onChange?
(isSelected: boolean) => void;
onClick?
(e: MouseEvent<FocusableElement, MouseEvent>) => void;
onPress
instead. onClick
is an alias for onPress
provided for compatibility with other libraries. onPress
provides
additional event details for non-mouse interactions.onClickCapture?
MouseEventHandler<HTMLLabelElement>;
onContextMenu?
MouseEventHandler<HTMLLabelElement>;
onContextMenuCapture?
MouseEventHandler<HTMLLabelElement>;
onDoubleClick?
MouseEventHandler<HTMLLabelElement>;
onDoubleClickCapture?
MouseEventHandler<HTMLLabelElement>;
onFocus?
(e: FocusEvent<Element, Element>) => void;
onFocusChange?
(isFocused: boolean) => void;
onGotPointerCapture?
PointerEventHandler<HTMLLabelElement>;
onGotPointerCaptureCapture?
PointerEventHandler<HTMLLabelElement>;
onHoverChange?
(isHovering: boolean) => void;
onHoverEnd?
(e: HoverEvent) => void;
onHoverStart?
(e: HoverEvent) => void;
onKeyDown?
(e: KeyboardEvent) => void;
onKeyUp?
(e: KeyboardEvent) => void;
onLostPointerCapture?
PointerEventHandler<HTMLLabelElement>;
onLostPointerCaptureCapture?
PointerEventHandler<HTMLLabelElement>;
onMouseDown?
MouseEventHandler<HTMLLabelElement>;
onMouseDownCapture?
MouseEventHandler<HTMLLabelElement>;
onMouseEnter?
MouseEventHandler<HTMLLabelElement>;
onMouseLeave?
MouseEventHandler<HTMLLabelElement>;
onMouseMove?
MouseEventHandler<HTMLLabelElement>;
onMouseMoveCapture?
MouseEventHandler<HTMLLabelElement>;
onMouseOut?
MouseEventHandler<HTMLLabelElement>;
onMouseOutCapture?
MouseEventHandler<HTMLLabelElement>;
onMouseOver?
MouseEventHandler<HTMLLabelElement>;
onMouseOverCapture?
MouseEventHandler<HTMLLabelElement>;
onMouseUp?
MouseEventHandler<HTMLLabelElement>;
onMouseUpCapture?
MouseEventHandler<HTMLLabelElement>;
onPointerCancel?
PointerEventHandler<HTMLLabelElement>;
onPointerCancelCapture?
PointerEventHandler<HTMLLabelElement>;
onPointerDown?
PointerEventHandler<HTMLLabelElement>;
onPointerDownCapture?
PointerEventHandler<HTMLLabelElement>;
onPointerEnter?
PointerEventHandler<HTMLLabelElement>;
onPointerLeave?
PointerEventHandler<HTMLLabelElement>;
onPointerMove?
PointerEventHandler<HTMLLabelElement>;
onPointerMoveCapture?
PointerEventHandler<HTMLLabelElement>;
onPointerOut?
PointerEventHandler<HTMLLabelElement>;
onPointerOutCapture?
PointerEventHandler<HTMLLabelElement>;
onPointerOver?
PointerEventHandler<HTMLLabelElement>;
onPointerOverCapture?
PointerEventHandler<HTMLLabelElement>;
onPointerUp?
PointerEventHandler<HTMLLabelElement>;
onPointerUpCapture?
PointerEventHandler<HTMLLabelElement>;
onPress?
(e: PressEvent) => void;
onPressChange?
(isPressed: boolean) => void;
onPressEnd?
(e: PressEvent) => void;
onPressStart?
(e: PressEvent) => void;
onPressUp?
(e: PressEvent) => void;
onScroll?
UIEventHandler<HTMLLabelElement>;
onScrollCapture?
UIEventHandler<HTMLLabelElement>;
onTouchCancel?
TouchEventHandler<HTMLLabelElement>;
onTouchCancelCapture?
TouchEventHandler<HTMLLabelElement>;
onTouchEnd?
TouchEventHandler<HTMLLabelElement>;
onTouchEndCapture?
TouchEventHandler<HTMLLabelElement>;
onTouchMove?
TouchEventHandler<HTMLLabelElement>;
onTouchMoveCapture?
TouchEventHandler<HTMLLabelElement>;
onTouchStart?
TouchEventHandler<HTMLLabelElement>;
onTouchStartCapture?
TouchEventHandler<HTMLLabelElement>;
onTransitionCancel?
TransitionEventHandler<HTMLLabelElement>;
onTransitionCancelCapture?
TransitionEventHandler<HTMLLabelElement>;
onTransitionEnd?
TransitionEventHandler<HTMLLabelElement>;
onTransitionEndCapture?
TransitionEventHandler<HTMLLabelElement>;
onTransitionRun?
TransitionEventHandler<HTMLLabelElement>;
onTransitionRunCapture?
TransitionEventHandler<HTMLLabelElement>;
onTransitionStart?
TransitionEventHandler<HTMLLabelElement>;
onTransitionStartCapture?
TransitionEventHandler<HTMLLabelElement>;
onWheel?
WheelEventHandler<HTMLLabelElement>;
onWheelCapture?
WheelEventHandler<HTMLLabelElement>;
readOnly?
boolean;
"false"
ref?
Ref<HTMLLabelElement>;
ref.current
to null
(or call the ref with null
if you passed a callback ref).
@see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}required?
boolean;
"false"
slot?
string | null;
null
value indicates that the local props completely override all props received from a parent.translate?
"yes" | "no";
validate?
(value: boolean) => true | ValidationError | null;
validationBehavior="native"
. For realtime validation, use the isInvalid
prop instead.validationBehavior?
"native" | "aria";
'native'
value?
string;
Checkbox.Group
aria-describedby?
string;
aria-details?
string;
aria-errormessage?
string;
aria-label?
string;
aria-labelledby?
string;
children?
ReactNode;
collapseAt?
number;
"undefined"
defaultValue?
string[]
description?
ReactNode;
dir?
string;
disabled?
boolean;
"false"
error?
boolean;
true
, the checkbox is considered invalid and if set the errorMessage
is shown instead of the description
."false"
errorMessage?
ReactNode | ((v: ValidationResult) => ReactNode);
form?
string;
<form>
element to associate the input with.
The value of this attribute must be the id of a <form>
in the same document.
See MDN.hidden?
boolean;
id?
string;
inert?
boolean;
label?
ReactNode;
lang?
string;
name?
string;
onAnimationEnd?
AnimationEventHandler<HTMLDivElement>;
onAnimationEndCapture?
AnimationEventHandler<HTMLDivElement>;
onAnimationIteration?
AnimationEventHandler<HTMLDivElement>;
onAnimationIterationCapture?
AnimationEventHandler<HTMLDivElement>;
onAnimationStart?
AnimationEventHandler<HTMLDivElement>;
onAnimationStartCapture?
AnimationEventHandler<HTMLDivElement>;
onAuxClick?
MouseEventHandler<HTMLDivElement>;
onAuxClickCapture?
MouseEventHandler<HTMLDivElement>;
onBlur?
(e: FocusEvent<Element, Element>) => void;
onChange?
(value: string[]) => void;
onClick?
MouseEventHandler<HTMLDivElement>;
onClickCapture?
MouseEventHandler<HTMLDivElement>;
onContextMenu?
MouseEventHandler<HTMLDivElement>;
onContextMenuCapture?
MouseEventHandler<HTMLDivElement>;
onDoubleClick?
MouseEventHandler<HTMLDivElement>;
onDoubleClickCapture?
MouseEventHandler<HTMLDivElement>;
onFocus?
(e: FocusEvent<Element, Element>) => void;
onFocusChange?
(isFocused: boolean) => void;
onGotPointerCapture?
PointerEventHandler<HTMLDivElement>;
onGotPointerCaptureCapture?
PointerEventHandler<HTMLDivElement>;
onLostPointerCapture?
PointerEventHandler<HTMLDivElement>;
onLostPointerCaptureCapture?
PointerEventHandler<HTMLDivElement>;
onMouseDown?
MouseEventHandler<HTMLDivElement>;
onMouseDownCapture?
MouseEventHandler<HTMLDivElement>;
onMouseEnter?
MouseEventHandler<HTMLDivElement>;
onMouseLeave?
MouseEventHandler<HTMLDivElement>;
onMouseMove?
MouseEventHandler<HTMLDivElement>;
onMouseMoveCapture?
MouseEventHandler<HTMLDivElement>;
onMouseOut?
MouseEventHandler<HTMLDivElement>;
onMouseOutCapture?
MouseEventHandler<HTMLDivElement>;
onMouseOver?
MouseEventHandler<HTMLDivElement>;
onMouseOverCapture?
MouseEventHandler<HTMLDivElement>;
onMouseUp?
MouseEventHandler<HTMLDivElement>;
onMouseUpCapture?
MouseEventHandler<HTMLDivElement>;
onPointerCancel?
PointerEventHandler<HTMLDivElement>;
onPointerCancelCapture?
PointerEventHandler<HTMLDivElement>;
onPointerDown?
PointerEventHandler<HTMLDivElement>;
onPointerDownCapture?
PointerEventHandler<HTMLDivElement>;
onPointerEnter?
PointerEventHandler<HTMLDivElement>;
onPointerLeave?
PointerEventHandler<HTMLDivElement>;
onPointerMove?
PointerEventHandler<HTMLDivElement>;
onPointerMoveCapture?
PointerEventHandler<HTMLDivElement>;
onPointerOut?
PointerEventHandler<HTMLDivElement>;
onPointerOutCapture?
PointerEventHandler<HTMLDivElement>;
onPointerOver?
PointerEventHandler<HTMLDivElement>;
onPointerOverCapture?
PointerEventHandler<HTMLDivElement>;
onPointerUp?
PointerEventHandler<HTMLDivElement>;
onPointerUpCapture?
PointerEventHandler<HTMLDivElement>;
onScroll?
UIEventHandler<HTMLDivElement>;
onScrollCapture?
UIEventHandler<HTMLDivElement>;
onTouchCancel?
TouchEventHandler<HTMLDivElement>;
onTouchCancelCapture?
TouchEventHandler<HTMLDivElement>;
onTouchEnd?
TouchEventHandler<HTMLDivElement>;
onTouchEndCapture?
TouchEventHandler<HTMLDivElement>;
onTouchMove?
TouchEventHandler<HTMLDivElement>;
onTouchMoveCapture?
TouchEventHandler<HTMLDivElement>;
onTouchStart?
TouchEventHandler<HTMLDivElement>;
onTouchStartCapture?
TouchEventHandler<HTMLDivElement>;
onTransitionCancel?
TransitionEventHandler<HTMLDivElement>;
onTransitionCancelCapture?
TransitionEventHandler<HTMLDivElement>;
onTransitionEnd?
TransitionEventHandler<HTMLDivElement>;
onTransitionEndCapture?
TransitionEventHandler<HTMLDivElement>;
onTransitionRun?
TransitionEventHandler<HTMLDivElement>;
onTransitionRunCapture?
TransitionEventHandler<HTMLDivElement>;
onTransitionStart?
TransitionEventHandler<HTMLDivElement>;
onTransitionStartCapture?
TransitionEventHandler<HTMLDivElement>;
onWheel?
WheelEventHandler<HTMLDivElement>;
onWheelCapture?
WheelEventHandler<HTMLDivElement>;
orientation?
AlignmentProp;
"vertical"
readOnly?
boolean;
"false"
required?
boolean;
"false"
slot?
string | null;
null
value indicates that the local props completely override all props received from a parent.translate?
"yes" | "no";
validate?
(value: string[]) => true | ValidationError | null;
validationBehavior="native"
. For realtime validation, use the isInvalid
prop instead.validationBehavior?
"native" | "aria";
'native'
value?
string[]
width?
WidthProp;
"full"
Alternative components
Choosing the right alternative to checkbox is important for providing an optimal user experience, especially when different types of selections are required. Depending on the nature of the choices and the desired interaction, the following components can serve as an alternative to checkboxes:
- Switch: When there is only on option that should have an immediate effect.
- Radio: When only one option can be selected from a set, a radio group is an alternative to a checkbox group, as radio buttons restrict the selection to a single option.
- SelectList: When you need more than just a text label to represent options, a
<SelectList>
can be used instead. - TagGroup: When you want to visually highlight selected options as individual tags or want a horizontal list of options, use the
<Tag>
component.