A checkbox lets the user turn one or more options on or off, independently of each other. The choice is saved when the form is submitted.
Tokens, sizes, measurements, states and requirements. Values come from the live token package and from Figma: Checkbox.
Resolved from the live token package.
| Mode | Part · state | Token | Value |
|---|
The checkmark and dash are SVG data URIs, which cannot use var(). Their colors (white, black, #939595 for the disabled check) are set in the SVG and match icon-inverted, surface-100 and surface-40.
| Size | Area | Box | Margin | Gap to label | Label |
|---|---|---|---|---|---|
| Large · Desktop | 24×24px | 16×16px | 4px | 8px | body-md: 17/24, 0.32px (769px and up) |
| Large · Mobile | 24×24px | 16×16px | 4px | 8px | body-md: 16/22, 0.32px (below 769px) |
| Small · both | 20×20px | 14×14px | 3px | 4px | body-sm: 14/20 |
| Inline menu | Box as above, then a 24×24px dropdown arrow (icon-primary, dark: icon-inverted). Gap 8px Large, 4px Small. No label. | ||||
Breakpoint. Figma has two versions of every checkbox: “XLarge–Large–Medium” (Desktop) and “Small–XSmall” (Mobile). In Figma the box, area, gap and Small label are the same in both; only the Large label differs, following body-md (17/24 on Desktop, 16/22 on Mobile). The component switches at 769px by itself. The Breakpoint toggle in the Playground on Examples & Guidelines forces one of them for preview only.
| Tile | Desktop | Mobile | Inside | Border (enabled) |
|---|---|---|---|---|
| Color swatch | 24×24px | 24×24px | 16px swatch, 2px padding | 1px border-secondary |
| Image | 48×48px | 40×40px | image 6px from the edge, object-fit: contain | 1px border-primary |
| Number | 48×48px | 40×40px | label-md 16/16, 0.48px, Bold, uppercase | 1px border-secondary |
Hover is 1px border-hover, selected is a 2px border-selected frame, selected hover is a 2px border-selected-hover frame. The fill is surface-raised-primary. In Figma the mobile Color Swatch has a 20×18px swatch box in the selected states; this page uses the 16px swatch for every state and breakpoint.
Box and margin of each size. The shaded area is the 4px margin (3px in Small) that leaves room for the focus ring; the lines show its value.
| Attribute | Large | Small (.form-checkbox-item--sm) |
|---|---|---|
| Area | 24×24px | 20×20px |
| Box | 16×16px, 1px border (dark mode: 2px on hover) | 14×14px |
| Margin around the box | 4px | 3px |
| Focus ring | 2px line, 2px offset (fills the 4px margin) | 2px line, 1px offset (fills the 3px margin) |
| Gap to the label | 8px | 4px |
| Checkmark | 16px mark in the box | 12px (background-size) |
| Corners | Square | |
The same margin and gap values as spacing tokens.
| Part | Large | Small |
|---|---|---|
| Margin around the box | space-4 | 3px: no spacing token |
| Gap box to label | space-8 | space-4 |
| Gap box to arrow (Inline menu) | space-8 | space-4 |
There is no spacing token for 3px. The Small margin is 3px in Figma. Open point: keep 3px, or add a token.
Every state for each value. Hover and focus are forced on this page with data-state so they can be seen at the same time; in your code they come from :hover and :focus-visible. The cells are live, so click to change the value (disabled cells do not respond).
| State | Unchecked | Checked | Mixed |
|---|
A checked checkbox in hover is “Selected hover”, in focus “Selected focus”. Every state in Figma is shown: nothing is left out for any size, mode or type.
Enabled, hover, selected and selected hover for each tile. Hover is forced on this page. The Number tile only has enabled and hover in Figma.
| State | Color swatch | Image | Number |
|---|
Selected is a 2px frame, drawn as a 1px border plus a 1px inset line so the tile never changes size. Disabled is not defined in Figma for tiles.
| Part | Type | Size / line height | Letter spacing | Weight |
|---|---|---|---|---|
| Label, Large | body-md | 16/22 mobile, 17/24 from 769px | 0.32px | Regular |
| Label, Small | body-sm | 14/20 | 0.36px | Regular |
| Number tile | label-md | 16/16 | 0.48px | Bold, uppercase |
| Filter row name and count | body-md | 16/22 mobile, 17/24 from 769px | 0.32px | Regular |
| Color name in the library | alt-label-lg | 16/16 mobile, 18/18 from 769px | 0.32px / 0.36px | Medium, uppercase |
Breuer Condensed. The disabled label uses text-disabled.
| Element | Property | Value |
|---|---|---|
| Area | Size | 24×24px (Large), 20×20px (Small): the box plus margin |
| Box | Shape | Square, 1px border, appearance: none on the native input |
| Checkmark and dash | Drawing | SVG data URI as background-image. Never an image file. |
| Label | Element | <span> inside the <label>; 8px (Large) or 4px (Small) from the box |
| Arrow (Inline menu) | Size | 24×24px, .cb-arrow, icon-primary (dark: icon-inverted) |
| Type | Class | Use |
|---|---|---|
| Standard | .form-checkbox-item | Box and label. |
| Small | .form-checkbox-item--sm | Dense layouts: tables, filters. |
| Dark | .form-checkbox-item--dark | On surface-100 or surface-80. |
| Inline menu | .form-checkbox-item--menu with .cb-arrow | Table header: select all and open a menu. No label. |
| Check icon | .check-icon on the cell | Read-only permission in a table. Always disabled, light only. |
| Tile: color swatch | .form-checkbox-tile | Filtering and PDP. Needs --swatch. |
| Tile: image | .form-checkbox-tile--image | PDP: one at a time with radio. |
| Tile: number | .form-checkbox-tile--number | A <button> with “+10”. |
| Filter row | .form-checkbox-tile--row | Color tile with name and count; the whole row is the click target. |
None. The checkbox changes state at once, with no transition and no animation.
| Input | Result |
|---|---|
| Click box or label | Toggles checked. Clearing the mixed state also makes it checked. |
| Tab / Shift+Tab | Moves between checkboxes. The focus ring shows with :focus-visible only. |
| Space | Toggles the focused checkbox. |
| Mixed | Set input.indeterminate = true in JavaScript. It cannot be set in HTML. |
| Disabled | Not focusable, no hover. The label turns text-disabled through :has(input:disabled). |
| Without label | Add aria-label. Never use an image or SVG file for the box. |
| Topic | Requirement |
|---|---|
| Element | A native <input type="checkbox">. The role, the state and the keyboard behavior come from the browser. |
| Name | A visible <label>, or aria-label when there is no text (Inline menu, tiles, table rows). |
| Group | Related checkboxes in a <fieldset> with a <legend>. |
| Mixed | Set with indeterminate in JavaScript, so assistive technology reads “mixed”. |
| Focus | Ring with border-focus, 2px, offset 2px, on :focus-visible (WCAG 2.4.7, 1.4.11). |
| Disabled | Not focusable. The label and the box use disabled tokens, which are exempt from contrast requirements. |
| Tiles | No visible label: aria-label is required. On a PDP, show the name of the chosen option next to the group so the choice is not carried by the picture alone. |
| Color | Selected is not shown by color alone: it adds a checkmark (box) or a thicker frame (tile). |