Wrap an <input type="checkbox"> in a
<label> to make the control. The label text
sits next to the input as a sibling and needs no extra class or
<span>. Checkboxes are CSS only, with no
JavaScript component to AutoInit.
Tokens follow the
M3 checkbox spec.
The container is 18dp with 2dp corners. Unselected is a 2dp
on-surface-variant outline. Selected is a
primary fill with an on-primary
check. Indeterminate is the same fill with a dash. The state
layer is 40dp at 8% hover and 10% focus. The touch target is
48dp. The label is body-large /
on-surface. Disabled is 38%.
Put the input first. Add checked or
disabled on the input. Indeterminate is not an
HTML attribute. Set element.indeterminate = true
in script. filled-in does nothing because the selected
state is always the filled box.
<label>
<input type="checkbox">
Red
</label>
<label>
<input type="checkbox" checked>
Yellow
</label>
<label>
<input type="checkbox" disabled>
Brown
</label>
document.getElementById('indeterminate-checkbox').indeterminate = true;
An input + span still works if you already have
that markup, including the
<label class="checkbox"> pattern. Multiple
<select> still emits
input + span that way.
<label class="checkbox">
<input type="checkbox">
<span>Yellow</span>
</label>
In a row
Put the labels in a <div class="inline"> to sit them on one
line. A bare group stacks vertically.
<div class="inline">
<label>
<input type="checkbox" checked>
Red
</label>
<label>
<input type="checkbox">
Yellow
</label>
</div>
Error
Add aria-invalid="true" or
class="invalid" on the input. The box uses
error / on-error. Forced-colors mode has
no error color, so the box gets a dashed edge there instead. Either
way, say what is wrong in text next to the box.
<label>
<input type="checkbox" aria-invalid="true">
Accept the terms
</label>