Checkbox

A checkbox lets people choose any number of options from a list, or confirm a single one, such as agreeing to terms. A dash marks a partial choice, which is how a parent checkbox shows that only some of its children are ticked. Watch the chameleon's checklist below: a box ticks, and a badge comes and goes.

Blend in Roll one eye Catch the cricket Hold still Turn the whole body orange Sunbathe Stay in the shade Photograph a leaf Nap Change color, again Wiggle Look both ways Eat lunch Bask Stay put Tongue out Go unnoticed Rest an eye

Reference docs⁠

BlazorReactWebOverviewExamplesAPIStylingAccessibility

Choosing a selection control⁠

Four components capture a choice in a form. Each suits a different job:

  • Checkbox: one or more options picked from a short list, or a single yes to confirm, such as "I agree to the terms".
  • Switch: a setting that takes effect the moment it is flipped, such as Wi-Fi or dark mode.
  • Radio buttons: exactly one option from a short list shown in full, such as delivery speed.
  • Select: exactly one option from a longer list kept closed until opened, such as country.

Two jobs belong elsewhere. A choice made by clicking a compact tag, such as filtering results, is a filter chip, and a two-state setting in a toolbar is a toggle button.

Built in⁠

  • The default slot is the label, and a click on it toggles the box.
  • indeterminate shows a partial selection with a dash.
  • A badge needs no separate element: badge-value sets its text, badge-dot makes it a dot, and badge-concealed hides it until you clear it.
  • name, form-value, and form-is-required make the checkbox take part in a form, including required validation and form reset.
  • Its touch target is at least 48 by 48 pixels even when the box paints smaller (touch-target).
  • label-position puts the label before or after the box, with no extra markup.

Using checkboxes well⁠

  • In a list with sub-selections, set indeterminate on the parent yourself: checked when every child is, unchecked when none is, indeterminate when some are.

These rules follow Material 3 Expressive's guidance for checkboxes, on material.io.

States⁠

checked sets whether the box is ticked, and indeterminate shows a partial selection with a dash. While indeterminate is set, the box paints as indeterminate whatever checked holds. A click on an indeterminate checkbox clears it, as a native checkbox does.

Touch target⁠

touch-target sets the area that takes a touch, and your style configuration supplies it when omitted, overflow unless you changed it. overflow spills an area of at least 48 by 48 pixels past the box, wrapper gives that area layout space, and none shrinks it to the box.

Badges⁠

badge-value puts text on the badge, badge-dot shows a dot instead, and badge-concealed hides the badge while keeping its settings. Clear badge-concealed and the same badge returns.

Forms⁠

name sets the key a checked box submits under, and form-value sets its value, which is on when omitted. Two boxes can share a name, so each checked box adds its own value. An unchecked or indeterminate box submits nothing. form-is-required makes an unchecked box invalid, and form reset restores the checked attribute.

Tick the terms and the state below follows; Start over returns the form to its authored state. The preview cannot submit a form, but a page that holds the same markup submits topics and terms as written, and refuses to submit while a required box is unticked.

Disabled⁠

disabled stops the checkbox taking focus or clicks and removes it from the Tab order. A disabled <fieldset> disables the checkboxes it contains without setting disabled on each.

Label position⁠

label-position takes leading or trailing, and the default is trailing. Leading draws the label before the box, and trailing draws it after.

Parent and children⁠

A parent checkbox is checked when all its children are, unchecked when none are, and indeterminate when some are. The component does not work this out: the page sets checked and indeterminate on the parent from its children. In the demo, the two buttons set every child at once, and the switch sets the parent to its partly selected state.

Properties⁠

PropertyAttributeTypeDescription
badgeConcealedbadge-concealedbooleandefault falseHides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges.
badgeDotbadge-dotbooleandefault falseShows the badge as a small dot with no text, whether or not badgeValue is set. See Badges.
badgeValuebadge-valuestringThe badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges.
checkedcheckedbooleandefault falseWhether the checkbox is checked. A user's click updates it, and a form reset restores the state the checked attribute gave it. See States, Parent and children.
disableddisabledbooleanWhether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled.
formread-onlyHTMLFormElementThe form the component belongs to, or null when it has none.
formIsRequiredform-is-requiredbooleandefault falseWhen true, require the checkbox to be checked when participating in form submission.See MDN: checkbox validation. See Forms.
formValueform-valuestringdefault onThe value submitted with a form while the checkbox is checked and not indeterminate.See MDN: checkbox value. See Forms.
indeterminateindeterminatebooleandefault falseWhether the checkbox shows the mixed state. A user's click clears it. While it is set, checked is not shown and the checkbox submits no value.See MDN: indeterminate state checkboxes. See States, Parent and children.
labelPositionlabel-positionleading, trailingLabelPositionLabelPosition.Leading, .Trailingdefault LabelPosition.TrailingSets which side of the checkbox the label is on. See Label position.
labelsread-onlyNodeListThe <label> elements associated with the element.
namenamestringThe name the element's value is submitted under with its form. See Forms.
touchTargettouch-targetnone, overflow, wrapperTouchTargetTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configurationThe area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target.
validationMessageread-onlystringThe message describing why the element is invalid, or an empty string when it is valid.
validityread-onlyValidityStateThe element's ValidityState.
willValidateread-onlybooleanWhether the element takes part in constraint validation. False while it is disabled or read-only.

Slots⁠

SlotDescription
(default)The label content.

Events⁠

EventTypeDetailDescription
changeEvent—Fired after a user toggles the checkbox. Setting checked from code does not fire it. It bubbles.
inputInputEvent—Fired as a user toggles the checkbox. Setting checked from code does not fire it. It bubbles and is composed.

Methods⁠

MethodReturnsDescription
checkValidity()booleanChecks the element's validity and returns true if it is valid. If not, it dispatches an invalid event; nothing changes on screen.
reportValidity()booleanChecks the element's validity and returns true if it is valid. If not, it dispatches a cancelable invalid event and, unless a listener cancels it, shows validationMessage as the field's error text and focuses the field.
setCustomValidity(error: string)voidSets a custom validation message, which makes the element invalid. An empty string clears it.

Props⁠

PropTypeDescription
badgeConcealedbooleandefault falseHides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges.
badgeDotbooleandefault falseShows the badge as a small dot with no text, whether or not badgeValue is set. See Badges.
badgeValuestringThe badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges.
checkedbooleandefault falseWhether the checkbox is checked. A user's click updates it, and a form reset restores the state the checked attribute gave it. See States, Parent and children.
disabledbooleanWhether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled.
formread-only (ref)HTMLFormElementThe form the component belongs to, or null when it has none.
formIsRequiredbooleandefault falseWhen true, require the checkbox to be checked when participating in form submission.See MDN: checkbox validation. See Forms.
formValuestringdefault onThe value submitted with a form while the checkbox is checked and not indeterminate.See MDN: checkbox value. See Forms.
indeterminatebooleandefault falseWhether the checkbox shows the mixed state. A user's click clears it. While it is set, checked is not shown and the checkbox submits no value.See MDN: indeterminate state checkboxes. See States, Parent and children.
labelPositionLabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.TrailingSets which side of the checkbox the label is on. See Label position.
labelsread-only (ref)NodeListThe <label> elements associated with the element.
namestringThe name the element's value is submitted under with its form. See Forms.
touchTargetTouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configurationThe area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target.
validationMessageread-only (ref)stringThe message describing why the element is invalid, or an empty string when it is valid.
validityread-only (ref)ValidityStateThe element's ValidityState.
willValidateread-only (ref)booleanWhether the element takes part in constraint validation. False while it is disabled or read-only.

Children⁠

ChildDescription
childrenThe label content.

Events⁠

PropArgumentDescription
onChangeReact.ChangeEvent<HTMLInputElement>Fired after a user toggles the checkbox. Setting checked from code does not fire it. It bubbles.
onInputReact.ChangeEvent<HTMLInputElement>Fired as a user toggles the checkbox. Setting checked from code does not fire it. It bubbles and is composed.

Methods⁠

Call these on the element the ref holds.

MethodReturnsDescription
checkValidity()booleanChecks the element's validity and returns true if it is valid. If not, it dispatches an invalid event; nothing changes on screen.
reportValidity()booleanChecks the element's validity and returns true if it is valid. If not, it dispatches a cancelable invalid event and, unless a listener cancels it, shows validationMessage as the field's error text and focuses the field.
setCustomValidity(error: string)voidSets a custom validation message, which makes the element invalid. An empty string clears it.

Parameters⁠

ParameterTypeDescription
BadgeConcealedbool?default falseHides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges.
BadgeDotbool?default falseShows the badge as a small dot with no text, whether or not BadgeValue is set. See Badges.
BadgeValuestring?The badge's text. While it is empty and BadgeDot is not set, no badge renders. Ignored if BadgeDot is set. See Badges.
Disabledbool?Whether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled.
FormIsRequiredbool?default falseWhen true, require the checkbox to be Checked when participating in form submission.See MDN: checkbox validation. See Forms.
FormValuestring?default onThe value submitted with a form while the checkbox is checked and not indeterminate.See MDN: checkbox value. See Forms.
Indeterminatebool?default falseWhether the checkbox shows the mixed state. A user's click clears it. While it is set, Checked is not shown and the checkbox submits no value.See MDN: indeterminate state checkboxes. See States, Parent and children.
LabelPositionLabelPosition?LabelPosition.Leading, .Trailingdefault LabelPosition.TrailingSets which side of the checkbox the label is on. See Label position.
Namestring?The name the element's value is submitted under with its form. See Forms.
TouchTargetTouchTarget?TouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configurationThe area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target.
Valuebool—
ValueExpressionExpression<Func<bool>>?Gets or sets an expression that identifies the bound value.

Render fragments⁠

ParameterTypeDescription
ChildContentRenderFragment?The label content.

Event callbacks⁠

ParameterTypeDescription
OnChangeEventCallback<ChangeEventArgs>Fired after a user toggles the checkbox. Setting Checked from code does not fire it. It bubbles.
OnInputEventCallback<ChangeEventArgs>Fired as a user toggles the checkbox. Setting Checked from code does not fire it. It bubbles and is composed.

Inputs⁠

InputTypeDescription
badgeConcealedbooleandefault falseHides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges.
badgeDotbooleandefault falseShows the badge as a small dot with no text, whether or not badgeValue is set. See Badges.
badgeValuestringThe badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges.
checkedbooleandefault falseWhether the checkbox is checked. A user's click updates it, and a form reset restores the state the checked attribute gave it. See States, Parent and children.
disabledbooleanWhether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled.
formIsRequiredbooleandefault falseWhen true, require the checkbox to be checked when participating in form submission.See MDN: checkbox validation. See Forms.
formValuestringdefault onThe value submitted with a form while the checkbox is checked and not indeterminate.See MDN: checkbox value. See Forms.
indeterminatebooleandefault falseWhether the checkbox shows the mixed state. A user's click clears it. While it is set, checked is not shown and the checkbox submits no value.See MDN: indeterminate state checkboxes. See States, Parent and children.
labelPositionLabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.TrailingSets which side of the checkbox the label is on. See Label position.
namestringThe name the element's value is submitted under with its form. See Forms.
touchTargetTouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configurationThe area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target.
valueboolean—

Content projection⁠

ContentDescription
content with no slotThe label content.

Outputs⁠

OutputEventDescription
cwChangeEventFired after a user toggles the checkbox. Setting checked from code does not fire it. It bubbles.
cwInputInputEventFired as a user toggles the checkbox. Setting checked from code does not fire it. It bubbles and is composed.

Props⁠

PropTypeDescription
badgeConcealedbooleandefault falseHides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges.
badgeDotbooleandefault falseShows the badge as a small dot with no text, whether or not badgeValue is set. See Badges.
badgeValuestringThe badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges.
checkedbooleandefault falseWhether the checkbox is checked. A user's click updates it, and a form reset restores the state the checked attribute gave it. See States, Parent and children.
disabledbooleanWhether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled.
formIsRequiredbooleandefault falseWhen true, require the checkbox to be checked when participating in form submission.See MDN: checkbox validation. See Forms.
formValuestringdefault onThe value submitted with a form while the checkbox is checked and not indeterminate.See MDN: checkbox value. See Forms.
indeterminatebooleandefault falseWhether the checkbox shows the mixed state. A user's click clears it. While it is set, checked is not shown and the checkbox submits no value.See MDN: indeterminate state checkboxes. See States, Parent and children.
labelPositionLabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.TrailingSets which side of the checkbox the label is on. See Label position.
namestringThe name the element's value is submitted under with its form. See Forms.
touchTargetTouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configurationThe area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target.

Slots⁠

SlotDescription
defaultThe label content.

Events⁠

EventTypeDescription
changeEventFired after a user toggles the checkbox. Setting checked from code does not fire it. It bubbles.
inputInputEventFired as a user toggles the checkbox. Setting checked from code does not fire it. It bubbles and is composed.

Props⁠

PropTypeDescription
badgeConcealedbooleandefault falseHides the badge while keeping its value and dot setting, so clearing this property shows the same badge again. See Badges.
badgeDotbooleandefault falseShows the badge as a small dot with no text, whether or not badgeValue is set. See Badges.
badgeValuestringThe badge's text. While it is empty and badgeDot is not set, no badge renders. Ignored if badgeDot is set. See Badges.
checkedbooleandefault falseWhether the checkbox is checked. A user's click updates it, and a form reset restores the state the checked attribute gave it. See States, Parent and children.
disabledbooleanWhether the element is disabled. Also reads true while a disabled <fieldset> contains it. See Disabled.
formIsRequiredbooleandefault falseWhen true, require the checkbox to be checked when participating in form submission.See MDN: checkbox validation. See Forms.
formValuestringdefault onThe value submitted with a form while the checkbox is checked and not indeterminate.See MDN: checkbox value. See Forms.
indeterminatebooleandefault falseWhether the checkbox shows the mixed state. A user's click clears it. While it is set, checked is not shown and the checkbox submits no value.See MDN: indeterminate state checkboxes. See States, Parent and children.
labelPositionLabelPositionTypeLabelPosition.Leading, .Trailingdefault LabelPosition.TrailingSets which side of the checkbox the label is on. See Label position.
namestringThe name the element's value is submitted under with its form. See Forms.
touchTargetTouchTargetTypeTouchTarget.None, .Overflow, .Wrapperdefault TouchTarget.Overflow, from the style configurationThe area that takes a touch, at least 48 by 48 pixels and centered on the component. overflow extends it past the component without changing the component's layout size, wrapper makes the component take up the whole area in the layout, and none limits it to the component's own size. See Touch target.

Snippets⁠

SnippetDescription
childrenThe label content.

Events⁠

PropTypeDescription
onChangeEventFired after a user toggles the checkbox. Setting checked from code does not fire it. It bubbles.
onInputInputEventFired as a user toggles the checkbox. Setting checked from code does not fire it. It bubbles and is composed.

A value is what the token defaults to; selecting it copies the token's name.

Tokens⁠

TokenValue
--ct-checkbox-container-size18px --ct-checkbox-container-size
--ct-checkbox-disabled-container-opacity0.38 --ct-checkbox-disabled-container-opacity
--ct-checkbox-disabled-label-text-color--ct-sys-color-on-surface --ct-checkbox-disabled-label-text-color
--ct-checkbox-disabled-label-text-opacity0.38 --ct-checkbox-disabled-label-text-opacity
--ct-checkbox-disabled-outline-color--ct-sys-color-on-surface --ct-checkbox-disabled-outline-color
--ct-checkbox-focus-outline-color--ct-sys-color-on-surface --ct-checkbox-focus-outline-color
--ct-checkbox-focus-outline-width2px --ct-checkbox-focus-outline-width
--ct-checkbox-hover-outline-color--ct-sys-color-on-surface --ct-checkbox-hover-outline-color
--ct-checkbox-hover-outline-width2px --ct-checkbox-hover-outline-width
--ct-checkbox-hover-state-layer-color--ct-sys-color-on-surface --ct-checkbox-hover-state-layer-color
--ct-checkbox-hover-state-layer-opacity--ct-sys-state-hover-state-layer-opacity --ct-checkbox-hover-state-layer-opacity
--ct-checkbox-icon-size18px --ct-checkbox-icon-size
--ct-checkbox-label-gap18px --ct-checkbox-label-gap
--ct-checkbox-label-text-color--ct-sys-color-on-surface --ct-checkbox-label-text-color
--ct-checkbox-label-text-font--ct-sys-typescale-label-large-font --ct-checkbox-label-text-font
--ct-checkbox-label-text-line-height--ct-sys-typescale-label-large-line-height --ct-checkbox-label-text-line-height
--ct-checkbox-label-text-size--ct-sys-typescale-label-large-size --ct-checkbox-label-text-size
--ct-checkbox-label-text-weight--ct-sys-typescale-label-large-weight --ct-checkbox-label-text-weight
--ct-checkbox-outline-color--ct-sys-color-on-surface-variant --ct-checkbox-outline-color
--ct-checkbox-outline-width2px --ct-checkbox-outline-width
--ct-checkbox-pressed-outline-color--ct-sys-color-on-surface --ct-checkbox-pressed-outline-color
--ct-checkbox-pressed-outline-width2px --ct-checkbox-pressed-outline-width
--ct-checkbox-pressed-state-layer-color--ct-sys-color-primary --ct-checkbox-pressed-state-layer-color
--ct-checkbox-pressed-state-layer-opacity--ct-sys-state-pressed-state-layer-opacity --ct-checkbox-pressed-state-layer-opacity
--ct-checkbox-selected-container-color--ct-sys-color-primary --ct-checkbox-selected-container-color
--ct-checkbox-selected-disabled-container-color--ct-sys-color-on-surface --ct-checkbox-selected-disabled-container-color
--ct-checkbox-selected-disabled-container-opacity0.38 --ct-checkbox-selected-disabled-container-opacity
--ct-checkbox-selected-disabled-icon-color--ct-sys-color-surface --ct-checkbox-selected-disabled-icon-color
--ct-checkbox-selected-focus-icon-color--ct-sys-color-on-primary --ct-checkbox-selected-focus-icon-color
--ct-checkbox-selected-hover-icon-color--ct-sys-color-on-primary --ct-checkbox-selected-hover-icon-color
--ct-checkbox-selected-hover-state-layer-color--ct-sys-color-primary --ct-checkbox-selected-hover-state-layer-color
--ct-checkbox-selected-hover-state-layer-opacity--ct-sys-state-hover-state-layer-opacity --ct-checkbox-selected-hover-state-layer-opacity
--ct-checkbox-selected-icon-color--ct-sys-color-on-primary --ct-checkbox-selected-icon-color
--ct-checkbox-selected-pressed-icon-color--ct-sys-color-on-primary --ct-checkbox-selected-pressed-icon-color
--ct-checkbox-selected-pressed-state-layer-color--ct-sys-color-on-surface --ct-checkbox-selected-pressed-state-layer-color
--ct-checkbox-selected-pressed-state-layer-opacity--ct-sys-state-pressed-state-layer-opacity --ct-checkbox-selected-pressed-state-layer-opacity
--ct-checkbox-state-layer-radius--ct-sys-corner-radius-full --ct-checkbox-state-layer-radius
--ct-checkbox-state-layer-size40px --ct-checkbox-state-layer-size

Names and states⁠

A checkbox follows the WAI-ARIA Authoring Practices: Checkbox pattern. It is one focus stop.

  • The accessible name comes from the default slot, which labels the checkbox, or from aria-label.
  • Give a checkbox with no visible label an aria-label, and leave it empty, whitespace included.
  • aria-label and aria-invalid are the only ARIA attributes a checkbox honors. Any other aria-* you set on it has no effect.
  • aria-invalid is announced, but nothing draws an error state, so show your own error text beside the checkbox.
  • indeterminate is announced as mixed.
  • A badge is not part of the accessible name. A dot or concealed badge is hidden from assistive technology, so put any count that matters in the label.
  • A checkbox has no built-in tooltip. A standalone plain or rich tooltip anchored on it describes the checkbox, so a screen reader reads that tooltip's text after the name.
  • A setting that applies the moment it changes suits a switch, and exactly one choice from a short list suits radio buttons.

Keyboard and focus⁠

Key Action
Tab Moves focus to the checkbox, or past it
Shift+Tab Moves focus to the previous control
Space Toggles the checkbox

Space toggles and Tab moves on, as for a native checkbox; Enter does not toggle a checkbox.

  • A focus ring shows on keyboard focus only.
  • disabled removes the checkbox from the Tab order and stops activation. A disabled <fieldset> has the same effect on the checkboxes it contains.

Pointer and touch⁠

The touch target is at least 48 by 48 pixels, so with the default it exceeds the 24 by 24 pixels WCAG 2.5.8 asks for while the box paints smaller. Setting touch-target to none shrinks the touch area to the painted checkbox, so measure it against 2.5.8 before you use it.

Display settings⁠

  • Forced colors: the box outline is CanvasText (GrayText when disabled), and a checked fill is ButtonText with a Canvas mark. A disabled checked box drops the fill and draws a GrayText mark. Transitions stop, and hover draws a two-pixel ButtonText ring around the box and press a four-pixel one.
  • Reduced motion: the mark and fill transitions take no time, and the press ripple is skipped.

Standards⁠

With its defaults, the checkbox meets three WCAG 2.2 success criteria:

  • 2.1.1 Keyboard (A)
  • 2.4.7 Focus Visible (AA)
  • 2.5.8 Target Size (Minimum) (AA)

Three more depend on how you use it:

  • 3.3.1 Error Identification (A): show error text next to the checkbox, since aria-invalid draws nothing.
  • 3.3.2 Labels or Instructions (A): give every checkbox a visible label.
  • 4.1.2 Name, Role, Value (A): give a checkbox with no visible label an aria-label.