C-11 · Components · Inputs
All elements · Toggle on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Toggle
Approving as
Binary or tri-state choice as checkbox, switch or radio. The native input stays in the DOM (visually hidden) so forms and assistive tech work unchanged.
| Axis | Values |
|---|---|
data-appearance |
checkbox (default) · switch · radio |
data-size · data-label-placement |
md · sm / end (default) · start |
:checked · :indeterminate · :disabled |
native state |
.qf-toggle-group[data-orientation] |
vertical (default) · horizontal |
Guidance
When to use
- Use a checkbox for an option that is saved with the rest of a form, or to pick several items from a short list.
- Use the indeterminate checkbox for a parent option when only some children are selected, such as a select-all row.
-
Use a switch (
data-appearance="switch") for a setting that takes effect at once, such as "Include archived". - Use radios for one choice from two to five visible options.
When to consider something else
- If there are more than about five options, use a select. See Select.
- If the choice switches a view rather than setting a value, use a button group. See ButtonGroup.
- If the control runs an action, use a button. See Button.
Usability
- Write labels that describe the on state: "Only mine", not "Show all or only mine".
- Group related toggles in
.qf-toggle-groupwith a visible group label. - Pre-select a sensible radio so the group always has a value.
- Apply switch changes immediately and show the result.
- Don't use a switch inside a form that needs Save; use a checkbox.
- Don't use a single checkbox for a choice that needs a confirmation, such as accepting terms, without clear text.
- Don't use radios for on and off; use one checkbox or switch.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves focus to a checkbox or switch, or to the checked radio in a group. |
| Space | Checks or unchecks a checkbox or switch; selects the focused radio. |
| Arrow Up, Arrow Down, Arrow Left or Arrow Right | In a radio group, moves to and selects the previous or next radio (native behavior). |
Roles and names
-
A native
<input type="checkbox">ortype="radio"stays in the DOM, visually hidden, inside the<label>, so it has its name and state. -
The switch appearance is still a checkbox; the binding should add
role="switch"so it is announced as on or off. -
Indeterminate is set with the
indeterminateproperty in script, not with an attribute. -
A radio group needs
role="radiogroup"(or<fieldset>and<legend>) and a name; the specimen group has no name yet.
Focus
-
The focus ring is drawn on
.qf-toggle__boxwhen the hidden input has:focus-visible. - Disabled inputs leave the tab order; disabled radios are skipped by the arrow keys.
Other requirements
- Target size 2.5.8: the box is 18px, but the whole label is clickable and the row is at least 32px high.
- Checked, unchecked and indeterminate differ by a check or a dash and the fill, not color alone (1.4.1); the box border must reach 3:1 (1.4.11).
-
With
data-label-placement="start"the visual order is reversed but the label still belongs to its input (1.3.2).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (3 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (4 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- toggle --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.