Checkbox
Used in forms when a user needs to select multiple values from several options
Usage
import { Checkbox } from "chakra-ui-solid";<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label />
</Checkbox.Root>Checkbox.Root renders the <label> and Checkbox.HiddenInput renders the real
<input type="checkbox"> inside it, so a click anywhere in the row toggles the box. The input is
not optional — without it there is nothing focusable, nothing to submit, and nothing for the label
to point at.
If you prefer a closed component composition, check out the snippet below.
Shortcuts
The Checkbox component also provides a set of shortcuts for common use cases.
CheckboxControl
This component renders the Checkbox.Indicator within it by default.
This works:
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>This might be more concise, if you don’t need to customize the indicator:
<Checkbox.Control />Examples
Variants
Pass the variant prop to the Checkbox.Root component to change the visual style of the checkbox.
outline
subtle
solid
Colors
Pass the colorPalette prop to the Checkbox.Root component to change the color of the checkbox.
gray
red
green
blue
teal
pink
purple
cyan
orange
yellow
Sizes
Pass the size prop to the Checkbox.Root component to change the size of the checkbox.
States
Pass the disabled or invalid prop to the Checkbox.Root component to change the visual state of
the checkbox.
Controlled
Use the checked and onCheckedChange props to control the state of the checkbox.
Label Position
Here’s an example of how to change the label position to the right.
Store
An alternative way to control the checkbox is to use the RootProvider component and the
createCheckbox store hook.
This way you can access the checkbox state and methods from outside the checkbox.
checked: falseComposition
Here’s an example of how to compose a checkbox with a field component.
Form Validation
Here’s an example of a checkbox driven by a signal, with a validation message on submit.
Group
Use the CheckboxGroup component to group multiple checkboxes together.
Group Validation
The same, for a group: the ticked values are one array, and the message hangs off the fieldset.
Custom Icon
Render a custom icon within Checkbox.Control to change the icon of the checkbox.
To replace the mark for one state only, pass checked or indeterminate to Checkbox.Indicator.
Each is a function handed the indicator’s computed props, so spread them onto your glyph —
Merging the computed class is
what to read if your own class has to survive that spread.
Indeterminate
Set the checked prop to indeterminate to show the checkbox in an indeterminate state.
Description
Here’s an example of how to add some further description to the checkbox.
Link
Render an anchor tag within the Checkbox.Label to add a link to the label.
Closed Component
Here’s how to setup the Checkbox for a closed component composition.
Guides
CheckboxGroup + Field vs Fieldset
When working with multiple checkboxes, it’s important to understand the semantic difference between
Field and Fieldset:
- Single Checkbox: Wrap with
Field.Rootfor proper form field structure with labels and helper text - CheckboxGroup: Wrap with
Fieldset.Root, notField.Root
A checkbox group represents a collection of related options and should be marked up as a fieldset
with a legend, not as a single field. Wrapping CheckboxGroup in Field.Root can cause interaction
issues where only the first checkbox responds to clicks.
✅ Correct Usage:
<Fieldset.Root>
<CheckboxGroup name="framework">
<Fieldset.Legend>Select framework</Fieldset.Legend>
{/* ... checkboxes ... */}
</CheckboxGroup>
</Fieldset.Root>❌ Incorrect Usage:
// Don't wrap CheckboxGroup with Field.Root
<Field.Root>
<CheckboxGroup>{/* ... checkboxes ... */}</CheckboxGroup>
</Field.Root>Styling the box
The whole checkmark — the border, the radius, the fill and the size — is on the control slot, not
on Checkbox.Indicator. Style Checkbox.Control to change how the box looks; the indicator only
carries the glyph inside it.
<Checkbox.Control borderRadius="full" />Props
Root
| Prop | Default | Type |
|---|---|---|
checked | — | checkbox.CheckedStateThe controlled checked state. Pass `undefined` for uncontrolled. |
defaultChecked | — | checkbox.CheckedStateThe state a fresh, uncontrolled checkbox starts in. |
disabled | — | booleanWhether the checkbox can be toggled or focused at all. Inherited from a surrounding Field. |
form | — | stringThe id of a form elsewhere on the page that this checkbox submits with. |
id | — | stringSeeds every id the machine hands out — the root is `checkbox:{id}`, the hidden input `checkbox:{id}:input`. Defaults to a generated id, and **does not become the root element's own `id`**: pass `ids` to control the attributes themselves. |
ids | — | CheckboxElementIdsOverride individual element ids, for pointing an ARIA relationship at a specific one. |
invalid | — | booleanWhether the checkbox shows its error treatment. Inherited from a surrounding Field. |
name | — | stringThe hidden input's `name`, for form submission. |
onCheckedChange | — | (details: CheckboxCheckedChangeDetails) => voidCalled whenever the checked state changes, from either side. |
readOnly | — | booleanWhether the checkbox refuses to change while staying focusable. Inherited from a Field. |
required | — | booleanWhether the form requires this box to be ticked. Inherited from a surrounding Field. |
size | 'md' | ConditionalValue<'xs' | 'sm' | 'md' | 'lg' | PresetVariant<'checkbox', 'size'>>The box's size, its gap to the label, and the label's text style. |
value | 'on' | stringThe hidden input's `value`, for form submission — and the key a `<CheckboxGroup>` tracks this box by. |
variant | 'solid' | ConditionalValue<'outline' | 'solid' | 'subtle' | PresetVariant<'checkbox', 'variant'>>How the box is painted once it is ticked. |
Plus Omit<HTMLChakraProps<"label">, "id"> — the whole style-prop surface and the DOM attributes of the element it renders, several hundred names listed as their sources rather than expanded — and the three every component takes: as, render and unstyled.
RootProvider
| Prop | Default | Type |
|---|---|---|
size | 'md' | ConditionalValue<'xs' | 'sm' | 'md' | 'lg' | PresetVariant<'checkbox', 'size'>>The box's size, its gap to the label, and the label's text style. |
value* | — | CreateCheckboxReturnA machine built by {@link createCheckbox}, so the consumer owns it rather than the Root. |
variant | 'solid' | ConditionalValue<'outline' | 'solid' | 'subtle' | PresetVariant<'checkbox', 'variant'>>How the box is painted once it is ticked. |
Plus HTMLChakraProps<"label"> — the whole style-prop surface and the DOM attributes of the element it renders, several hundred names listed as their sources rather than expanded — and the three every component takes: as, render and unstyled.
Indicator
| Prop | Default | Type |
|---|---|---|
checked | — | RenderProp<ComponentProps<'svg'>>Draws instead of the tick while the box is checked. |
indeterminate | — | RenderProp<ComponentProps<'svg'>>Draws instead of the dash while the box is indeterminate. |
Plus HTMLChakraProps<"svg"> — the whole style-prop surface and the DOM attributes of the element it renders, several hundred names listed as their sources rather than expanded — and the three every component takes: as, render and unstyled.
Group
| Prop | Default | Type |
|---|---|---|
defaultValue | — | string[]The values ticked in a fresh, uncontrolled group. |
disabled | — | booleanDisables every checkbox in the group. Inherited from a surrounding Fieldset. |
invalid | — | booleanMarks every checkbox in the group invalid. Inherited from a surrounding Fieldset. |
maxSelectedValues | — | numberHow many boxes may be ticked at once — the unticked ones disable themselves at the ceiling. |
name | — | stringThe `name` every checkbox in the group submits under. |
onValueChange | — | (value: string[]) => voidCalled with the whole new set whenever any box in the group changes. |
readOnly | — | booleanMakes every checkbox in the group read-only. |
value | — | string[]The controlled set of ticked values. Pass `undefined` for uncontrolled. |
Plus HTMLChakraProps<"div"> — the whole style-prop surface and the DOM attributes of the element it renders, several hundred names listed as their sources rather than expanded — and the three every component takes: as, render and unstyled.