Checkboxes allow the user to toggle the field state on (checked) or off (unchecked). They are mainly used in a couple of scenarios:
A single checkbox: Used for binary choices, such as acknowledging terms and conditions in sign-up forms. Typically, this is represented by a boolean value.
A checkbox group: Used to represent multiple choices, such as updating email marketing preferences. This can be represented by an array of values for each selected choice.
Checkboxes are more nuanced than that, and we’ve put a lot of thought into how they should behave as components.
You can build checkboxes using either native HTML input[type="checkbox"] elements or other HTML elements. We provide behavior, state, and accessibility implementation for both cases with the same API and features.
Currently, the following features are implemented:
Support for either input[type="checkbox"] or any other HTML elements as a base element for the checkbox.
Automatic linking of labels, descriptions, and error messages to input and label elements with aria-* attributes.
Custom checked/unchecked values.
Support for the indeterminate state.
Form management, data collection, and validation with Standard Schemas or native HTML5 validation.
Support for orientation with horizontal and vertical values.
v-model support for both single and grouped checkboxes.
Supported Keyboard features:
Key
Description
⎵Space
Selects the focused checkbox item.
⇥Tab
Moves the focus to the next checkbox item or the next tab order element in the document.
⇧Shift + ⇥Tab
Moves the focus to the previous checkbox item or the previous tab order element in the document.
Anatomy
Input
I accept the terms
Checkbox Label
Choose Drink
Group Label
Tea
Coffee
Input
Water
Checkbox Label
Checkbox Group
Building a Checkbox component
The useCheckbox composable provides the behavior, state, and accessibility implementation for checkbox items. Checkbox items can be built with either input[type="checkbox"] or custom HTML elements depending on your styling needs.
You can start by importing the useCheckbox composable and using it in your checkbox component.
The useCheckbox composable returns binding objects for the elements shown in the anatomy. You will use v-bind to bind them to the DOM elements.
These bindings contain all the necessary attributes and event listeners to manage the checkbox state and behavior and to ensure support for assistive technologies.
With that out of the way, let’s see how you can build a checkbox component. There are two ways to do it.
With input as a base element
This is how you would build a custom checkbox item component using the useCheckbox composable.
With the native input being limited in terms of styling, you can consider hiding it visually and instead use a custom element in its place. Note that while the element is visually hidden, it will still be announced by assistive technologies. Alternatively, you can use any element as a base instead.
The .sr-only class is used to hide the input element from the visual layout but keep it accessible to assistive technologies. You should have a similar class in your styling solution or framework as this use-case is very common.
Another thing to note is we’ve placed the input element inside a label element to ensure that the checkbox is still focusable and that clicking on the label also toggles the checkbox.
With other HTML elements as a base
For special styling needs, you don’t have to use the input element. You can use a custom HTML element as a base with the same API.
Building a Checkbox Group component
You will use the useCheckboxGroup composable to build a checkbox group component. The composable offers the behavior, state, and accessibility implementation for checkbox groups.
Assuming that you’ve already built a checkbox component using the useCheckbox composable as the two are tightly coupled, the following example shows how you can build a checkbox group component.
We will use a checkbox without an input element base just to show you that it does not matter what element you use as a base. The same behaviors will be provided for either.
Validation
Checkbox components and checkbox groups can be validated by using Standard Schemas or native HTML5 validation via the schema prop on each of them.
When checkboxes are a part of a checkbox group, they will not report their own error messages as the group component should be responsible for displaying the error message.
HTML Constraints
The following properties are supported on both composables if you use the input element as a base for the checkbox.
Name
Type
Description
required
boolean
Whether the checkbox or group is required.
Here is an example of how to use the required property on either a CheckboxItem or a CheckboxGroup.
Note that marking any checkbox item that is part of a checkbox group as required will not make the group required and it will be ignored.
Standard Schema
Both useCheckbox and useCheckboxGroup support Standard Schema validation through the schema prop. This includes multiple providers like Zod, Valibot, Arktype, and more.
Usage
Disabled
You can disable individual checkboxes or the whole group with the disabled prop on either. Disabled checkboxes are not focusable. Disabled groups are not submitted and are not validated.
If you need to prevent the user from interacting with the checkboxes while still allowing it to submit, consider using readonly instead.
Readonly
Only available on the group and group-less checkboxes. The readonly prop prevents the user from interacting with the group/checkbox while still allowing it to submit and be validated.
Indeterminate
Only available on the checkbox item. The indeterminate state is used to model a tri-state checkbox. One of the situations it is used in is when a checkbox group has a mix of checked and unchecked items.
Checkboxes that are indeterminate will change their checked state until the indeterminate state is removed.
Group Checked State
The overall checked state of a group is reported via the groupState property on the useCheckboxGroup composable. The groupState property is an enum that represents if the group is entirely checked, unchecked, or mixed.
We will use a few SVGs to represent the group state visually.
API
Checkbox
Props
These are the properties that can be passed to the useCheckbox composable.
Name
Type
Description
disabled
Whether the checkbox is disabled.
disableHtmlValidation
Whether HTML5 validation should be disabled for this checkbox.
falseValue
The value to use when unchecked.
indeterminate
Whether the checkbox is in an indeterminate state.
label
The label for the checkbox.
modelValue
The current value of the checkbox.
name
The name/path of the checkbox field.
readonly
Whether the checkbox is readonly.
required
Whether the checkbox is required.
schema
The validation schema for the checkbox.
standalone
Whether the checkbox should operate independently of any checkbox group.
trueValue
The value to use when checked.
value
The value to use when part of a checkbox group.
Returns
These are the properties in the object returned by the useCheckbox composable.