Checkbox
A box the reader ticks to agree to something or to pick any number of options.
Checkbox is a box and its label as one control. The choice is recorded, not applied: it takes effect when the reader submits the form or confirms the step. Checkbox Group labels a set of checkboxes that answer one question and holds their combined value.
Variants
Sizes
<Checkbox defaultSelected>Medium</Checkbox>
<Checkbox size="sm" defaultSelected>
Small
</Checkbox>md is the default, a 16px box. sm is a 14px box for dense lists, such as
the rows of a multi-select Select.
Tone
<Checkbox defaultSelected>Brand</Checkbox>
<Checkbox tone="neutral" defaultSelected>
Neutral
</Checkbox>
<Checkbox tone="neutral" isIndeterminate>
Neutral indeterminate
</Checkbox>brand is the default: a checked or indeterminate box fills brand blue. Use
neutral in products whose UI is monochrome; the box fills with the primary
gray and the check or dash uses the inverse foreground, so it reads in light
and dark mode. An invalid box is red in either tone. To set the tone for a
whole product or form, pass it once through CheckboxPropsContext; it reaches
checkboxes inside a Checkbox Group too. See
Manual.
Unchecked and checked
<Checkbox>Unchecked</Checkbox>
<Checkbox defaultSelected>Checked</Checkbox>Pass defaultSelected for uncontrolled use and isSelected with onChange
when the parent owns the state.
Indeterminate
<Checkbox isIndeterminate>Select all</Checkbox>isIndeterminate shows a dash instead of a check. Use it on a "Select all"
checkbox when only some of the options under it are checked. It is a display
state the parent sets: clicking the checkbox does not clear it, so recompute
it from the children's values.
Invalid
<Checkbox isInvalid>I agree to the Base Privacy Policy</Checkbox>
<Checkbox isInvalid defaultSelected>
Checked
</Checkbox>
<Checkbox isInvalid isIndeterminate>
Indeterminate
</Checkbox>isInvalid gives an unchecked box a red border. A checked or indeterminate
box fills red instead of its tone color, and has a white check or dash.
Inside a Checkbox Group, pass errorMessage to the group instead so the
message is shown with the options.
Disabled
<Checkbox isDisabled>Disabled</Checkbox>
<Checkbox isDisabled defaultSelected>
Disabled and checked
</Checkbox>Checkbox Group
<CheckboxGroup
label="Categories"
description="Pick any that apply."
defaultValue={['defi']}
>
<Checkbox value="defi">DeFi</Checkbox>
<Checkbox value="nft">NFT</Checkbox>
<Checkbox value="social">Social</Checkbox>
</CheckboxGroup>Give each checkbox in a group a value. The group's value is the array of
checked values, and errorMessage replaces the description and marks every
checkbox invalid.
<CheckboxGroup label="Categories" errorMessage="Pick at least one category.">
<Checkbox value="defi">DeFi</Checkbox>
<Checkbox value="nft">NFT</Checkbox>
</CheckboxGroup>When to use
Use Checkbox for a yes-or-no choice that is submitted with a form, such as agreeing to a policy, or for picking any number of options from a short list.
Use something else when:
- The change applies the moment it is made. Use Switch.
- The reader picks exactly one option. Use Segment for two to five short options, or Select for a longer list.
- The options are filters shown as removable chips above results. Use a tag
group (React Aria's
TagGroup); BDS does not ship one yet.
Usage
Do
Write the label as the thing the reader agrees to or picks: "I agree to the Base Privacy Policy", "Email me product updates". The label is part of the hit area, so the whole line is clickable.
Don't
Phrase the label as a negative, such as "Don't send me emails". Checking a box to turn something off makes the reader stop and think.
Group related checkboxes in a Checkbox Group with a label, rather than stacking loose checkboxes under a heading, so screen readers announce the question with each option.
Props
Checkbox
| Prop | Type | Default |
|---|---|---|
childrenThe children of the component. A function may be provided to alter the children based on | TypeChildrenOrFunction<CheckboxRenderProps> | Default— |
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<CheckboxRenderProps> | Default— |
defaultSelectedWhether the element should be selected (uncontrolled). | Typeboolean | Default— |
inputRefA ref for the HTML input element. | TypeRef<HTMLInputElement | null> | Default— |
isDisabledWhether the input is disabled. | Typeboolean | Default— |
isIndeterminateIndeterminism is presentational only. | Typeboolean | Default— |
isInvalidWhether the input value is invalid. | Typeboolean | Default— |
isReadOnlyWhether the input can be selected but not changed by the user. | Typeboolean | Default— |
isRequiredWhether user input is required on the input before form submission. | Typeboolean | Default— |
isSelectedWhether the element should be selected (controlled). | Typeboolean | Default— |
size | Type"md" | "sm" | null | Defaultmd |
toneThe checked fill: `brand` blue, or `neutral` gray for monochrome UIs. | Type"brand" | "neutral" | Defaultbrand |
validateA function that returns an error message if a given value is invalid. | Type((value: boolean) => true | ValidationError | null) | Default— |
validationBehaviorWhether to use native HTML form validation to prevent form submission | Type"native" | "aria" | Default'native' |
CheckboxGroup
| Prop | Type | Default |
|---|---|---|
childrenThe checkboxes in the group. | TypeReactNode | Default— |
classNameThe CSS [className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className) for the | TypeClassNameOrFunction<CheckboxRenderProps> | Default— |
defaultValueThe default value (uncontrolled). | Typestring[] | Default— |
description | TypeReactNode | Default— |
errorMessage | TypeChildrenOrFunction<FieldErrorRenderProps> | Default— |
isDisabledWhether the input is disabled. | Typeboolean | Default— |
isInvalidWhether the input value is invalid. | Typeboolean | Default— |
isReadOnlyWhether the input can be selected but not changed by the user. | Typeboolean | Default— |
isRequiredWhether user input is required on the input before form submission. | Typeboolean | Default— |
label | TypeReactNode | Default— |
validateA function that returns an error message if a given value is invalid. | Type((value: boolean) => true | ValidationError | null) | Default— |
validationBehaviorWhether to use native HTML form validation to prevent form submission | Type"native" | "aria" | Default'native' |
CheckboxIndicator
The box and its mark on their own, with no input. Use it inside a control that
already reports its state, such as a multiple-selection
Select option, which carries aria-selected. It is
hidden from assistive technology and never takes focus, so the row stays one
control. For a choice of its own, use Checkbox.
| Prop | Type | Default |
|---|---|---|
isFocusVisibleShows the keyboard focus ring on the box. | Typeboolean | Defaultfalse |
isIndeterminate | Typeboolean | Defaultfalse |
isInvalid | Typeboolean | Defaultfalse |
isSelected | Typeboolean | Defaultfalse |
size | Type"md" | "sm" | null | Defaultmd |
toneThe checked fill. Defaults to the `tone` set on `CheckboxPropsContext`, | Type"brand" | "neutral" | Default— |
Accessibility
Checkbox wraps React Aria's Checkbox, which renders a real checkbox input,
so it is reachable by keyboard and toggles with Space. Passing children
labels it; without children, pass aria-label. In development, a Checkbox
with neither logs a console warning. An indeterminate checkbox sets the
input's native indeterminate property, which assistive technology announces
as mixed. The box and its check or dash are decorative and hidden from
assistive technology.
Checkbox Group wraps React Aria's CheckboxGroup, which renders a group
named by its label and linked to its description and error message. Without
label, pass aria-label; in development, a Checkbox Group with neither logs
a console warning.
The check or dash draws in from its leading edge over 150ms. It appears instantly when the checkbox is toggled from the keyboard, when the reader prefers reduced motion, and on first render.