Checkbox
Checkboxes allow a user to select zero, one, or multiple values from a predefined list of 7 or less options.
Component Type
Input
Platform
Web
Component
Sana Canvas
Delivery Channels
Web, Web Mobile
Version
16.1.7Experience Surfaces
Page Body Inline
Anatomy

- Form Field Label: The Form Field Label describes all of the checkboxes in the checkbox group and functions as a header.
- Checkbox: Checkboxes are aligned close to its label or by itself in some cases.
- Checkbox Label: Checkbox Labels give information about what to select or unselect.
Usage Guidance
- The Form Field Label can be positioned in two places; above or left of the checkbox group for LTR languages. Form Field Labels are aligned to the right of the checkbox group for RTL languages.
- Checkbox Labels are positioned to the right of Checkboxes for LTR languages or to the left of Checkboxes for RTL languages.
- Checkboxes allow users to select one or many options. Selected options are shown as a white check with blue fill. Clicking it again will deselect the choice.
- Each Checkbox is tied to a distinct value. Label for each selection should describe the choice and be kept as concise as possible.
When to Use
- Use Checkboxes when the user is allowed to select 0, 1, or multiple values from a predefined list of 7 or less options.
When to Use Something Else
- Consider using a Switch if the only options are yes or no.
- For a list between 2 to 7 predefined options, consider using Radio Buttons or a Select to select one option.
- Use a Prompt when the number of list items is large or unknown. Prompts have search capabilities and folders which provide users with the means to browse options. Prompts can be configured to support single or multi-select.
Examples
Basic Example
Checkbox may be used on its own without Form Field since it
includes a <label> with a for attribute referencing the underlying <input type="checkbox">
element. For checkboxes grouped with FormFieldGroup, see
FormField accessibility for hint, error, caution,
and required state wiring.
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return <Checkbox checked={checked} label="I agree to the terms" onChange={handleChange} />;
};
Inverse
Checkbox with inverse variation
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {Flex} from '@workday/canvas-kit-react/layout';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const styleOverrides = createStyles({
backgroundColor: system.color.surface.contrast.default,
padding: system.padding.md,
});
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<Flex cs={styleOverrides}>
<Checkbox
variant="inverse"
checked={checked}
label="I agree to the terms"
onChange={handleChange}
/>
</Flex>
);
};
Disabled
Set the disabled prop of the Checkbox to prevent users from interacting with it.
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<Checkbox checked={checked} disabled label="I agree to the terms" onChange={handleChange} />
);
};
Indeterminate
Set the indeterminate prop of the Checkbox to true to indicate the Checkbox is neither checked
nor unchecked.
A common use case for an indeterminate Checkbox is when the value of a parent Checkbox is dependent on a number of child Checkboxes. The parent Checkbox is set to the indeterminate state if some (but not all) of its children are checked.
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const listStyles = createStyles({
listStyle: 'none',
margin: 0,
padding: 0,
});
const nestedListStyles = createStyles({
listStyle: 'none',
margin: 0,
marginInlineStart: system.gap.xl,
marginBlockStart: system.gap.sm,
padding: 0,
display: 'flex',
flexDirection: 'column',
gap: system.gap.sm,
});
export default () => {
const [pizzaChecked, setPizzaChecked] = React.useState(false);
const [pizzaIndeterminate, setPizzaIndeterminate] = React.useState(false);
const [toppings, setToppings] = React.useState([
{name: 'Pepperoni', checked: false},
{name: 'Sausage', checked: false},
{name: 'Bell Peppers', checked: false},
{name: 'Olives', checked: false},
{name: 'Onions', checked: false},
]);
const handlePizzaChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const checked = event.target.checked;
if (checked || (!checked && pizzaIndeterminate)) {
setPizzaChecked(true);
setToppings(
toppings.map(topping => ({
...topping,
checked: true,
}))
);
} else {
setPizzaChecked(false);
setToppings(
toppings.map(topping => ({
...topping,
checked: false,
}))
);
}
setPizzaIndeterminate(false);
};
const handleToppingChange = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
const newToppings = toppings.map(topping => ({...topping}));
newToppings[index].checked = event.target.checked;
setToppings(newToppings);
const anyToppingChecked = newToppings.filter(topping => topping.checked).length > 0;
const anyToppingUnchecked = newToppings.filter(topping => !topping.checked).length > 0;
const allToppingChecked = !anyToppingUnchecked;
setPizzaIndeterminate(anyToppingChecked && anyToppingUnchecked);
setPizzaChecked(allToppingChecked);
};
return (
<ul className={listStyles}>
<li>
<Checkbox
checked={pizzaChecked}
indeterminate={pizzaIndeterminate}
label="Supreme Pizza Toppings"
onChange={handlePizzaChange}
/>
<ul className={nestedListStyles}>
{toppings.map((topping, index) => (
<li key={topping.name}>
<Checkbox
checked={topping.checked}
label={topping.name}
onChange={event => handleToppingChange(event, index)}
/>
</li>
))}
</ul>
</li>
</ul>
);
};
Accessibility Note: Use semantic unordered list markup so that screen readers can communicate the nested hierarchy of the components to users.
Ref Forwarding
Checkbox supports ref forwarding . It will forward
ref to its underlying <input type="checkbox"> element.
import React from 'react';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {changeFocus} from '@workday/canvas-kit-react/common';
import {Flex} from '@workday/canvas-kit-react/layout';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const containerStyles = createStyles({
gap: system.gap.md,
alignItems: 'flex-start',
flexDirection: 'column',
});
export default () => {
const [checked, setChecked] = React.useState(false);
const ref = React.useRef<HTMLInputElement>(null);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
const handleClick = () => {
changeFocus(ref.current);
};
return (
<Flex cs={containerStyles}>
<Checkbox checked={checked} label="I agree to the terms" onChange={handleChange} ref={ref} />
<PrimaryButton onClick={handleClick}>Focus Checkbox</PrimaryButton>
</Flex>
);
};
Label Position Horizontal
Set the orientation prop of the wrapping FormFieldGroup to designate the position of the group
label relative to the checkboxes. By default, the orientation will be set to vertical.
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<FormFieldGroup orientation="horizontalStart">
<FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
<FormFieldGroup.Field>
<FormFieldGroup.Input
as={Checkbox}
checked={checked}
label="I agree to the terms"
onChange={handleChange}
/>
</FormFieldGroup.Field>
</FormFieldGroup>
);
};
Required
Set the isRequired prop of a wrapping FormFieldGroup to true to indicate that the field is
required. Labels for required fields are suffixed by a red asterisk.
A standalone checkbox does not need FormFieldGroup. This example wraps a single checkbox so
isRequired can show the required asterisk on FormFieldGroup.Label. Use that wrapper only
when the spec includes a required state (or a group name, hint, error, or caution). See
Accessibility.
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<FormFieldGroup isRequired={true}>
<FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
<FormFieldGroup.Field>
<FormFieldGroup.Input
as={Checkbox}
checked={checked}
label="I agree to the terms"
onChange={handleChange}
/>
</FormFieldGroup.Field>
</FormFieldGroup>
);
};
Error States
Set the error prop of the wrapping FormFieldGroup to "caution" or "error" to set the Checkbox
to the Alert or Error state, respectively. Render FormFieldGroup.Hint with the message text so
assistive technology can associate the hint with the group. Keep the Checkbox label so each
control retains its own accessible name; FormFieldGroup.Label only provides the group name.
The error prop may be applied directly to the Checkbox with a value of "caution" or "error" if
FormFieldGroup is not being used.
Caution
You must agree to the terms before proceeding
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<FormFieldGroup error="caution">
<FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
<FormFieldGroup.Field>
<FormFieldGroup.Input
as={Checkbox}
checked={checked}
error={Checkbox.ErrorType.Caution}
label="I agree to the terms"
onChange={handleChange}
/>
<FormFieldGroup.Hint>You must agree to the terms before proceeding</FormFieldGroup.Hint>
</FormFieldGroup.Field>
</FormFieldGroup>
);
};
Error
You must agree to the terms before proceeding
import React from 'react';
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
import {FormFieldGroup} from '@workday/canvas-kit-react/form-field';
export default () => {
const [checked, setChecked] = React.useState(false);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setChecked(event.target.checked);
};
return (
<FormFieldGroup error="error">
<FormFieldGroup.Label>Confirm</FormFieldGroup.Label>
<FormFieldGroup.Field>
<FormFieldGroup.Input
as={Checkbox}
checked={checked}
error={Checkbox.ErrorType.Error}
label="I agree to the terms"
onChange={handleChange}
/>
<FormFieldGroup.Hint>You must agree to the terms before proceeding</FormFieldGroup.Hint>
</FormFieldGroup.Field>
</FormFieldGroup>
);
};
Custom Styles
Checkbox supports custom styling via the cs prop. For more information, check our
“How To Customize Styles” .
Accessibility
The primary accessibility goal is a visible, programmatically determinable name and a checked, unchecked, or mixed state that assistive technology can expose. Use Checkbox when the user can select zero, one, or many independent options. For mutually exclusive choices, use Radio instead. When checkboxes answer the same question, or need hint, error, caution, or required association, see FormField’s accessibility documentation.
Minimum Accessible Structure
The following matches the Basic Example: a Checkbox with a non-empty
label. FormFieldGroup is not required for a single standalone checkbox with no hint,
error, caution, or required state.
import {Checkbox} from '@workday/canvas-kit-react/checkbox';
<Checkbox label="I agree to the terms" />;Built-in Behaviors
Canvas Kit applies these automatically on Checkbox. When checkboxes that answer the same
question are composed with FormFieldGroup subcomponents, that grouping wiring is also applied
automatically. Do not duplicate them in consuming code.
ARIA and DOM (applied by Checkbox):
Checkbox: Renders a native<input type="checkbox">. Canvas Kit assigns anidwithuseUniqueIdunless you passid.label: Renders a visible<label htmlFor={id}>so the control has an accessible name and clicking the text activates the input.indeterminate: Setsaria-checked="mixed"and the input’s nativeindeterminateproperty. Otherwisearia-checkedfollows thecheckedprop.disabled: Maps to the nativedisabledattribute.ref: Forwards to the underlying<input type="checkbox">.
Keyboard (native checkbox behavior):
Checkbox uses native <input type="checkbox"> keyboard behavior (tab order, Space to toggle,
and label activation). Do not intercept Space or otherwise prevent the native toggle.
Screen reader expectations (when built-in behaviors are used as intended):
- On focus, assistive technology announces the Checkbox
labeland checked, unchecked, or mixed state - Disabled checkboxes are announced as unavailable
For group, hint, error, and required association, see FormField’s Built-in Behaviors.
Accessibility Requirements
Required in application code for an accessible Checkbox. Rows marked (conditional) apply only when the situation matches—otherwise omit.
If no design spec is provided: use a visible, non-empty Checkbox label. Omit
FormFieldGroup unless the spec includes a group name, more than one independent option for the
same question, or hint, error, caution, or required state. Omit FormFieldGroup.Hint,
isRequired, error, indeterminate, disabled, a custom id, and a
ref unless the spec requires them.
Choose a composition:
- Standalone
Checkboxwithlabel— one control with no hint, error, caution, or required state FormFieldGroup— one question with two or more independent options, or any checkbox that needs a group name, hint, error, caution, or required state- Nested
<ul>/<li>— parent checkbox with nested children andindeterminate. Do not useFormFieldGroupfor that hierarchy. Checkboxes that answer different questions stay in separate compositions.
Programmatic focus (conditional — omit by default):
Attach a ref only when the product must move focus to the checkbox after an action (for example,
Submit in Ref Forwarding). Do not attach a ref or call focus() unless the
design or developer asks for it.
| Requirement | How to satisfy |
|---|---|
| Accessible name | Non-empty label on every Checkbox. FormFieldGroup.Label names the group only (div with an id); it is not a <label> and does not replace label. |
| Group wiring (conditional) | When the spec is one question with two or more independent options, or includes a group name, hint, error, caution, or required state: FormFieldGroup + FormFieldGroup.Label + FormFieldGroup.Input as={Checkbox}. Put hint, error, caution, and required on the group — see FormField accessibility. See Required and Error States. |
| Visual error or caution (conditional) | When FormFieldGroup has error="error" or error="caution", also set error on Checkbox to the same state so the visual ring appears. See Caution and Error. |
| Indeterminate parent (conditional) | When a parent checkbox’s value depends on nested children and some (but not all) children are checked: set indeterminate on the parent Checkbox; keep a non-empty label on the parent and on each child; nest the children in a <ul> inside the parent’s <li>. See Indeterminate. |
| Disabled (conditional) | disabled on Checkbox when the spec marks the option unavailable. See Disabled. |
| Programmatic focus (conditional) | ref on Checkbox (or FormFieldGroup.Input) and move focus when the product requires it — omit by default (see Programmatic focus above and Ref Forwarding). |
Summary for code generation:
- REQUIRED: non-empty
label - CONDITIONAL:
FormFieldGroupfor one question with two or more independent options, or for hint, error, caution, or required;erroronCheckboxwhen the group is in caution or error; nested list +indeterminatefor a parent/child tree; disabled; programmatic focus viaref. See FormField accessibility for group hint, error, caution, and required.
Anti-Patterns
Do not generate code that does the following (see Accessibility Requirements above for what to supply instead):
- Manually set
aria-checkedorhtmlForonCheckbox, or pass anidwhen the spec does not require a known id — Canvas Kit wiresaria-checkedandhtmlFor, and assigns anidwithuseUniqueIdunless you pass one (see If no design spec is provided) - Ignore Choose a composition — do not wrap a standalone checkbox with no group name, hint,
error, caution, or required state in
FormFieldGroup; do not put different questions in one group; do not useFormFieldGroupfor a parent/child indeterminate tree - Wrap
CheckboxwithFormField.Input—Checkboxalready renders its own<label>. When a group is required, useFormFieldGroup.Input as={Checkbox}(see Group wiring) - Omit
labelbecauseFormFieldGroup.Labelis present — the group label does not name the individual control - Set
aria-checked="mixed"withoutindeterminate - Use
aria-disabledinstead ofdisabled—Checkboxmaps unavailability to the nativedisabledprop - Use
disabledwhen the spec says users must still focus the control to hear why it is unavailable. Only in that case keep the checkbox enabled and put the explanation inFormFieldGroup.Hintor on an adjacent focusable control - Use Checkbox for mutually exclusive choices — use Radio instead
Component API
Checkbox
Props
Props extend from input. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
checked | boolean | If true, set the Checkbox to the checked state. | false |
disabled | boolean | If true, set the Checkbox to the disabled state. | false |
error | | The type of error associated with the Checkbox (if applicable). | |
id | string | The HTML | |
indeterminate | boolean | If true, set the Checkbox to an indeterminate state. Use this on a Checkbox with nested child Checkboxes to denote that some (but not all) child Checkboxes are checked. | false |
label | string | The text of the Checkbox label. | '' |
onChange | (e: <>) => void | The function called when the Checkbox state changes. | |
value | string | The value of the Checkbox. | |
variant | 'inverse' | undefined | The variant for the checkbox | |
cs | | The | |
children | React.ReactNode | ||
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | input |
ref | React.Ref<R = input> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If |
Checkbox.ErrorType
Basic type information:
ErrorTypeContent Guidelines
- Form Field Labels are written in title case.
- The Checkbox Label for each individual selection are kept as concise as possible and written in sentence case.