Checkbox
Ticks one or more options on or off before you hit Save.
Examples
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, defaultCheckedbooleanonCheckedChange(checked: boolean, details) => voidindeterminatebooleandefaultfalsearia-invalidbooleandisabled, required, name, valuenative
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)