figma guide

Designing toggle switches and checkboxes in Figma: states, groups, and handoff

Design toggle switches and checkboxes in Figma with on/off states, indeterminate, grouped layouts, form validation, and Dev Mode specs engineers can ship without guessing.

Published
Updated
Jun 15, 2026
Read time
7 min
Level
Beginner

Quick answer

Checkboxes let users select one or more independent options; toggle switches flip a single setting on or off immediately. Build separate component sets: a Checkbox with variants for checked=unchecked | checked | indeterminate and state=default | focus | error | disabled, and a Switch with on=off | on plus the same interaction states. Use checkboxes for multi-select lists and consent; use switches for binary settings that apply without a Save button. Pair with forms, sliders, and accessibility plugins. Document label placement, group semantics, and whether changes save instantly in Dev Mode. Start from the Figma guides hub for input primitives.


Who this is for

  • Product designers shipping settings panels, filters, consent flows, and bulk-select tables.
  • Design system teams standardizing when to use checkbox vs switch vs radio group.
  • Engineers implementing ARIA roles, indeterminate parent rows, and instant-save vs form-submit behavior.

Checkbox vs switch vs radio: when to use which

ControlSelection modelTypical useSaves when
CheckboxIndependent on/off per itemMulti-select filters, terms acceptance, table row selectForm submit or immediate (document)
SwitchSingle binary settingNotifications on/off, dark mode, feature flagsUsually immediate
Radio groupExactly one of NPlan tier, shipping methodForm submit
Segmented controlOne of few visible optionsView mode, time rangeImmediate

Verdict: if the copy reads “Enable notifications,” use a switch. If it reads “I agree to the terms” or “Select all rows,” use a checkbox. If options are mutually exclusive, use segmented controls or radio groups instead.


Checkbox component anatomy

PartPurposeSpec tip
Hit targetTap/click areaMin 44×44px touch; box can be 16–20px
BoxVisual checked state16px sm, 20px md standard
Checkmark / dashChecked / indeterminateCentered; 2px stroke at md
LabelDescribes the optionClickable; wraps on mobile
Helper textExtra contextBelow label, not inside box
Error messageValidation failure”You must accept to continue”
Checkbox
├── Variant: checked=unchecked | checked | indeterminate
├── Variant: state=default | focus | error | disabled
├── Variant: size=sm | md
├── Layer: Row (auto layout horizontal, gap 8–12)
│   ├── Box (frame with corner radius 4px)
│   │   ├── Checkmark icon (checked)
│   │   └── Dash icon (indeterminate)
│   └── LabelBlock
│       ├── Label (text/body)
│       └── Helper (text/body-sm, optional)
└── Layer: Error text (optional, below row)

Bind checked colors to semantic color tokens. Use interactive components for hover on the row, not just the box.


Checkbox states

StateBoxLabelNotes
UncheckedEmpty borderDefault textNeutral border token
CheckedFilled + checkmarkDefault textUse brand or semantic fill
IndeterminateFilled + horizontal dashDefault textParent row in nested lists
FocusFocus ring on box or rowUnchanged2px ring; never remove for “clean” UI
ErrorError borderError label optionalPair with message below
DisabledMuted fill/borderMuted textcursor: not-allowed in spec

Indeterminate appears when a parent checkbox controls children and only some are selected—common in tables with “select all” headers.


Switch component anatomy

PartPurposeSpec tip
TrackBackground rail44×24px md common; pill radius
ThumbSliding circle20px diameter; 2px inset from track
LabelSetting nameLeft of switch (settings) or right (compact)
DescriptionSecondary copyBelow label for dense settings
Switch
├── Variant: on=off | on
├── Variant: state=default | focus | disabled
├── Variant: size=sm | md
├── Layer: Row (auto layout horizontal, space-between or label-left)
│   ├── LabelBlock (optional)
│   │   ├── Label
│   │   └── Description
│   └── Track
│       └── Thumb (position: left | right)
└── Layer: Helper / error (optional)

Animate thumb position in prototypes with smart animate between on/off frames if stakeholders need motion; document instant toggle for engineering.


Switch states

StateTrackThumbNotes
OffNeutral grayLeftDefault resting
OnBrand / success fillRightHigh contrast vs off
FocusUnchangedFocus ring on trackVisible keyboard path
Disabled offMuted trackMuted thumbEntire control inactive
Disabled onMuted brandMuted thumbShow locked-on settings clearly

Do not use a switch for destructive actions without confirmation—pair delete flows with modals.


Layout patterns for groups

PatternLayoutBest for
Vertical stackAuto layout vertical, 12–16px gapSettings, filters, consent
Inline pairTwo checkboxes in a rowWeekday toggles (Mon–Fri)
Nested treeParent + indented childrenPermissions, folder pickers
Table headerCheckbox in column headerBulk actions on data tables
Card listCheckbox leading each cardMulti-select inbox

For select all in tables, design three frames: none selected, all selected, partial (indeterminate parent).


Pairing with other patterns

NeedPatternLink
Form field wrapperLabel + checkbox + errorForms guide
Filter sidebarCheckbox listSearch UI
Settings pageSwitch rowsAccordions for grouped settings
Required consentCheckbox + submit disabledProgress steppers
Status tagsDo not confuse with chipsChips are display; checkboxes are input

Accessibility checklist

RequirementCheckboxSwitch
Rolerole="checkbox"role="switch"
State`aria-checked=“truefalse
Label<label for> or aria-labelledbySame
Grouprole="group" + aria-labelledby for setsFieldset legend pattern
FocusVisible focus ringVisible focus ring
Disabledaria-disabled or native disabledSame
Erroraria-invalid="true" + aria-describedbySame

Run accessibility plugins on contrast for unchecked boxes and off-state tracks—gray-on-white often fails WCAG.


Prototyping limits

Figma cannot persist checkbox state across navigations. For demos:

  1. Build frames: unchecked, checked, indeterminate, error, disabled.
  2. Use component properties or swap instances for settings screens.
  3. For switches, smart-animate thumb position between on/off variants.

Organize flows with sections per settings area.


Handoff to engineering

DeliverableCheckboxSwitch
checked / onbooleanboolean
indeterminateboolean (checkbox only)n/a
disabledbooleanboolean
name / valuefor form postssetting key
onChange timingon clickon click
Save behaviorimmediate vs form submitusually immediate
Label clicktoggles controltoggles control
Group labelstring for fieldsetsection heading
Error messagestringstring

Include both primitives in your Dev Mode handoff checklist. Publish under Patterns / Forms in your team library.


Real-world examples

Notification settings (switches)

List of switches with label left, control right. Each row: title + one-line description. Off states use neutral track; on uses brand green. Disabled row when user lacks permission—muted with lock icon.

Terms acceptance (checkbox)

Single required checkbox above primary submit. Error state on submit if unchecked: red border + “Accept the terms to continue.” Submit button stays enabled but shows error—document preferred validation pattern.

Data table bulk select (checkboxes)

Header checkbox cycles: unchecked → all → indeterminate when partial. Row checkboxes independent. Toolbar appears when ≥1 row selected—link to badges for selection count.


Common mistakes

MistakeConsequenceFix
Switch for multi-selectWrong control shippedUse checkbox list
Checkbox for mutually exclusive optionsMultiple selections allowedUse radio group
Tiny hit target (12px box only)Miss taps on mobile44px row min height
No indeterminate stateBroken “select all”Add third variant
Label not clickableFrustrating UXWire label to control in spec
Switch requires Save buttonConfusing mental modelInstant apply or use checkbox
Focus ring removedKeyboard users lostKeep 2px focus ring token
Same component for checkbox and switchWrong anatomySeparate component sets

FAQ

Checkbox or switch for “Remember me”?

Checkbox—it is part of a form submit flow, not an instant system setting.

Switch or checkbox for dark mode?

Switch—users expect immediate theme change without Save.

Where does indeterminate appear?

Parent checkboxes in trees and table headers when children are partially selected.

Checkbox inside a modal?

Yes—common for “Don’t show again” or destructive confirm. Keep label readable at modal width.


Bottom line

Treat checkboxes and switches as distinct primitives with clear selection semantics, full state matrices, and honest save behavior. Document indeterminate, group labels, and table bulk-select in Dev Mode. Continue with forms, segmented controls, sliders, and the tutorials hub.

Share on X

§ Keep reading

Related guides.