Checkbox

Ticks one or more options on or off before you hit Save.

Examples

Settings

Confirm before sending

Pick statements

Checked

  • falsedefault

  • true

  • indeterminate

States

  • rest

  • hover

  • focus

  • invalid

  • disabled

Usage

When to use it
Use
A yes or no option on a form that waits for a button: add captions, accept the terms.
Use
Several independent options where any number can be on.
Use
Select all above a list, using the mixed state.
Not for
The change applies as soon as it is pressed. Use Switch.
Not for
Exactly one of a few options. Use Radio.
Not for
A filter or topic toggled in a row. Use Chip.

Rules

8 rules
Must
Wrap the box and its text in one label so the whole line is the press target. Because a loose span beside the 20px box neither names it nor toggles it when pressed.
Must
Pass aria-label when there is no visible text beside the box. Because without it a screen reader announces "checkbox" with no name.
Must
Set indeterminate on a parent when only some children are checked; pressing it sets all or none. Because a plain unchecked parent reads as none selected while some bills are on.
Should
Align the box to the first line with items-start when the label can wrap.
Should
State the option as what turning it on does; never a negative or a question.
Never
Fill a checked row with lime; use bg-accent-wash on the row if needed. Because the checked box is lime too, so it disappears into a lime row.
Should
Give the row at least 44px of height on touch surfaces; the box is 20px.
Should
Set aria-invalid for an error and put the reason in FieldError.

Accessibility

4 checks
Role checkbox named by the wrapping label or aria-label; aria-checked is true, false or mixed.
Space toggles; Tab skips a disabled box.
Focus shows a 2px olive outline offset 2px.
Outline contrast is 3.4:1 on the page; the check on lime is 15.6:1.

Edge cases

5 edge cases
Long label
The label wraps beside the 20px box; use items-start.
Right to left
The box moves to the right edge; the check has no direction.
No label
No accessible name and a 20px target.
Forced colors
A checked or mixed box paints with Highlight and the check with HighlightText.
Saves on press
There is no pending state; use a Switch.

API

5 props
checked, defaultChecked
boolean
onCheckedChange
(checked: boolean, details) => void
indeterminate
boolean default false
aria-invalid
boolean
disabled, required, name, value
native

Tokens

17 tokens
--page
#ffffff
--control
#85827a
--radius-sm
6px
--fg-2
#4a4943
--accent
#e4f222
--accent-hover
#d6e41a
--accent-line
#7c8700
--on-accent
#0f0f0d
--danger
#d93636
--line-strong
#cfcdc6
--surface-2
#efeeea
--fg-disabled
#a6a49b
--ring
var(--accent-line)
--line-focus
2px
--focus-offset
2px
--dur-fast
140ms
--ease-out
cubic-bezier(0.16, 1, 0.3, 1)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.