Checkbox
formUSWDS-derived
A custom-styled checkbox with tile variant support.
Reference: USWDS documentation ↗
Variants
Checked
<div class="flex-checkbox">
<input class="flex-checkbox__input" id="cb-checked" type="checkbox" name="test" value="yes" checked=""/>
<label class="flex-checkbox__label" for="cb-checked">Pre-checked</label>
</div>Default
<fieldset>
<legend>Options</legend>
<div class="flex-checkbox">
<input class="flex-checkbox__input" id="cb-1" type="checkbox" name="options" value="1"/>
<label class="flex-checkbox__label" for="cb-1">Option 1</label>
</div>
<div class="flex-checkbox">
<input class="flex-checkbox__input" id="cb-2" type="checkbox" name="options" value="2"/>
<label class="flex-checkbox__label" for="cb-2">Option 2</label>
</div>
<div class="flex-checkbox">
<input class="flex-checkbox__input" id="cb-3" type="checkbox" name="options" value="3"/>
<label class="flex-checkbox__label" for="cb-3">Option 3</label>
</div>
</fieldset>Disabled
<div class="flex-checkbox">
<input class="flex-checkbox__input" id="cb-disabled" type="checkbox" name="test" value="no" disabled=""/>
<label class="flex-checkbox__label" for="cb-disabled">Disabled option</label>
</div>Indeterminate
<div class="flex-checkbox">
<input class="flex-checkbox__input" id="cb-indeterminate" type="checkbox" name="test" value="maybe" data-indeterminate=""/>
<label class="flex-checkbox__label" for="cb-indeterminate">Indeterminate</label>
</div>Tile
<fieldset>
<legend>Tile checkboxes</legend>
<div class="flex-checkbox" data-variant="tile">
<input class="flex-checkbox__input" id="cb-tile-1" type="checkbox" name="tiles" value="1"/>
<label class="flex-checkbox__label" for="cb-tile-1">Tile option 1</label>
</div>
<div class="flex-checkbox" data-variant="tile">
<input class="flex-checkbox__input" id="cb-tile-2" type="checkbox" name="tiles" value="2"/>
<label class="flex-checkbox__label" for="cb-tile-2">Tile option 2</label>
</div>
<div class="flex-checkbox" data-variant="tile">
<input class="flex-checkbox__input" id="cb-tile-3" type="checkbox" name="tiles" value="3" checked=""/>
<label class="flex-checkbox__label" for="cb-tile-3">Tile option 3</label>
</div>
</fieldset>Contract
Class mapping
| USWDS | Flex | Notes |
|---|---|---|
usa-checkbox | .flex-checkbox | Base checkbox wrapper |
usa-checkbox__input | .flex-checkbox__input | Hidden native checkbox input |
usa-checkbox__label | .flex-checkbox__label | Visible label with pseudo-element indicators |
usa-checkbox__input--tile | data-variant="tile" | Tile variant with bordered card appearance |
Verified properties
font-familyfont-sizeline-heightcolorcursorfont-weightpadding-leftpositiondisplayBehavior promises
- ○ Focus ring visible on keyboard focus
- ○ Checked state shows checkmark indicator
- ○ Disabled state prevents interaction
- ○ Indeterminate state shows dash indicator
Source CSS
Base styles: Choice Input Label Base
/* flex-checkbox -- USWDS Checkbox conformance
Extends: Choice Input Label Base (base-classes.css#choice-input)
Variants: default, tile
States: checked, disabled, indeterminate, focus-visible */
.flex-checkbox {
background-color: var(--flex-color-surface);
}
/* Visually hidden but accessible input.
Uses physical `left`/`right` (matching USWDS .usa-sr-only) rather than
logical `inset-inline-*` because the CSS bundler emits the logical
properties as lang-conditional `:-webkit-any()` rules that modern
browsers reject, leaving the input painted at its static position on
top of the fake box. Off-screen via `left: -999em` works identically
in LTR and RTL for a visually-hidden element. */
.flex-checkbox__input {
position: absolute;
left: -999em;
right: auto;
&:checked + .flex-checkbox__label::before {
background-color: var(--flex-color-accent);
box-shadow: 0 0 0 2px var(--flex-color-accent);
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='65' height='50' viewBox='0 0 65 50'%3E%3Cpath fill='%23FFF' fill-rule='evenodd' d='M63.268 7.063l-5.616-5.61C56.882.685 55.946.3 54.845.3s-2.038.385-2.808 1.155L24.951 28.552 12.81 16.385c-.77-.77-1.707-1.155-2.808-1.155-1.1 0-2.037.385-2.807 1.154l-5.616 5.61C.81 22.764.425 23.7.425 24.8s.385 2.035 1.155 2.805l14.947 14.93 5.616 5.61c.77.77 1.706 1.154 2.807 1.154s2.038-.384 2.808-1.154l5.616-5.61 29.894-29.86c.77-.77 1.157-1.707 1.157-2.805 0-1.101-.385-2.036-1.156-2.805l-.001-.002z'/%3E%3C/svg%3E"),
linear-gradient(transparent, transparent);
background-repeat: no-repeat;
background-position: center center;
background-size: 0.75rem auto;
}
&:focus + .flex-checkbox__label::before {
outline: 0.25rem solid var(--flex-blue-vivid-40);
outline-offset: 0.25rem;
}
&:disabled + .flex-checkbox__label::before {
background-color: var(--flex-color-surface);
box-shadow: 0 0 0 2px var(--flex-color-disabled);
}
&[data-indeterminate] + .flex-checkbox__label::before {
background-color: var(--flex-color-accent);
box-shadow: 0 0 0 2px var(--flex-color-accent);
background-image:
url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath fill='%23FFF' fill-rule='evenodd' d='M2.9 35.9c0 1.1.4 2 1.2 2.8s1.7 1.2 2.8 1.2h50.2c1.1 0 2-.4 2.8-1.2s1.2-1.7 1.2-2.8V28c0-1.1-.4-2-1.2-2.8S58.2 24 57.1 24H6.9c-1.1 0-2 .4-2.8 1.2S2.9 26.9 2.9 28z' clip-rule='evenodd'/%3E%3C/svg%3E"),
linear-gradient(transparent, transparent);
background-repeat: no-repeat;
background-position: center center;
background-size: 0.75rem auto;
}
&[data-indeterminate]:disabled + .flex-checkbox__label::before {
box-shadow: 0 0 0 2px var(--flex-color-disabled);
}
}
/* Label — component-specific overrides */
.flex-checkbox__label {
margin-block-start: 0.75rem;
padding-inline-start: 2rem;
/* Checkbox box (::before) */
&::before {
content: " ";
display: block;
position: absolute;
inset-inline-start: 0;
margin-inline-start: 2px;
margin-block-start: 0.064rem;
block-size: 1.25rem;
inline-size: 1.25rem;
border-radius: 2px;
background-color: var(--flex-color-surface);
box-shadow: 0 0 0 2px var(--flex-color-text);
outline: 2px solid transparent;
outline-offset: 2px;
}
}
/* --- Tile variant --- */
.flex-checkbox[data-variant="tile"] {
& .flex-checkbox__input + .flex-checkbox__label {
background-color: var(--flex-color-surface);
border: 2px solid var(--flex-gray-20);
border-radius: 0.25rem;
color: var(--flex-color-text);
margin-block-start: 0.5rem;
padding-block: 0.75rem;
padding-inline: 2.5rem 1rem;
display: inherit;
}
& .flex-checkbox__input:checked + .flex-checkbox__label {
background-color: color-mix(
in srgb,
var(--flex-color-accent) 10%,
transparent
);
border-color: var(--flex-color-accent);
}
& .flex-checkbox__input:disabled + .flex-checkbox__label {
border-color: var(--flex-gray-10);
}
& .flex-checkbox__input:disabled:checked + .flex-checkbox__label,
& .flex-checkbox__input:disabled[data-indeterminate] + .flex-checkbox__label {
background-color: var(--flex-color-surface);
}
& .flex-checkbox__input[data-indeterminate] + .flex-checkbox__label {
background-color: color-mix(
in srgb,
var(--flex-color-accent) 10%,
transparent
);
border-color: var(--flex-color-accent);
}
}
A digital services project by Flexion