Skip to content

Checkbox

wu-checkbox styles a native checkbox and its label. The box is 1em, so it follows the root type size. The check mark and the indeterminate dash are drawn in CSS.

Class or state Effect
wu-checkbox Root, on <label>. Box and label in a row
wu-checkbox-input Part, on <input type="checkbox">. The box; also works alone with aria-label
wu-checkbox-label Part. The label text
sm, lg Small and large type size, so a smaller or larger box
checked, indeterminate Brand fill with a check mark or a dash
aria-invalid="true" or :user-invalid 2px danger edge, kept on hover and when checked
disabled Lower opacity on the whole label, not-allowed cursor
<div class="flex col gap-2">
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" checked>
<span class="wu-checkbox-label">Email me about new comments</span>
</label>
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox">
<span class="wu-checkbox-label">Email me about new followers</span>
</label>
</div>

HTML has no attribute for the mixed state. Set the indeterminate property from a script:

document.getElementById('checkbox-all').indeterminate = true;
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" id="checkbox-all">
<span class="wu-checkbox-label">Select all</span>
</label>
<div class="flex col gap-2">
<label class="wu-checkbox sm">
<input class="wu-checkbox-input" type="checkbox" checked>
<span class="wu-checkbox-label">Small</span>
</label>
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" checked>
<span class="wu-checkbox-label">Default</span>
</label>
<label class="wu-checkbox lg">
<input class="wu-checkbox-input" type="checkbox" checked>
<span class="wu-checkbox-label">Large</span>
</label>
</div>

The invalid border shows with aria-invalid="true", or after the user has interacted with a required box (:user-invalid).

<div class="flex col gap-2">
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" aria-invalid="true">
<span class="wu-checkbox-label">I accept the terms</span>
</label>
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" disabled>
<span class="wu-checkbox-label">Disabled</span>
</label>
<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" checked disabled>
<span class="wu-checkbox-label">Disabled and checked</span>
</label>
</div>

Without the label, the input part works on its own, for example in a table row. Give it an aria-label.

<input class="wu-checkbox-input" type="checkbox" aria-label="Select row">
  • The control is a native checkbox inside its <label>, so clicking the text toggles it and Space toggles it from the keyboard.
  • Keyboard focus shows the focus ring from the border-focus tokens.
  • In forced colors mode the box uses system colors.

The box sits on the inline start, so it moves to the right.

<label class="wu-checkbox">
<input class="wu-checkbox-input" type="checkbox" checked>
<span class="wu-checkbox-label">تذكرني</span>
</label>
@use "@wovenui/components/checkbox";

The checkbox needs no other component.