Browse Components

Checkbox

Independent choices with clear labels and native behavior.

Basic

Click the label or focus the checkbox and press Space.

View Code
HTML
<label class="checkbox">
  <input type="checkbox" name="updates" value="email">
  <span>
    Email me project updates
  </span>
</label>

With a description

Connect helpful context to the control.

A weekly summary. You can change this preference later.

View Code
HTML
<div class="field">
  <label class="checkbox">
    <input type="checkbox" aria-describedby="updates-help" name="updates" value="email">
    <span>
      Email me project updates
    </span>
  </label>
  <p id="updates-help" class="muted">
    A weekly summary. You can change this preference later.
  </p>
</div>

Grouped choices

A legend names the group. Choose any combination.

Notifications
View Code
HTML
<fieldset class="checkbox-group">
  <legend>
    Notifications
  </legend>
  <label class="checkbox">
    <input type="checkbox" name="updates" value="email">
    <span>
      Email me project updates
    </span>
  </label>
  <label class="checkbox">
    <input type="checkbox" checked name="mentions" value="email">
    <span>
      Email me project mentions
    </span>
  </label>
</fieldset>

Disabled

Explain why a choice is unavailable.

View Code
HTML
<label class="checkbox">
  <input type="checkbox" disabled checked name="updates" value="email">
  <span>
    Project updates are managed by your administrator
  </span>
</label>

Required and invalid

This example shows an error after validation. Your application clears the error once corrected.

Select this option to enable email delivery.

View Code
HTML
<div class="field">
  <label class="checkbox">
    <input
      type="checkbox"
      required
      aria-invalid="true"
      aria-describedby="checkbox-error"
      name="updates"
      value="email"
    >
    <span>
      Email me project updates
    </span>
  </label>
  <p class="field-error" id="checkbox-error">
    Select this option to enable email delivery.
  </p>
</div>

Mixed state

Mixed is a DOM property. Clicking clears it and toggles the native checked state.

View Code
HTML
<label class="checkbox">
  <input type="checkbox" id="mixed-choice" name="updates" value="email">
  <span>
    Some project updates selected
  </span>
</label>
<script>
  document.getElementById("mixed-choice").indeterminate=true;
</script>

Right-to-left

Logical spacing follows the reading direction.

View Code
HTML
<div dir="rtl" lang="he">
  <label class="checkbox">
    <input type="checkbox" name="updates" value="email">
    <span>
      שלחו לי עדכונים על הפרויקט
    </span>
  </label>
</div>

Without motion

The control still changes state immediately with motion disabled.

View Code
HTML
<div data-motion="none">
  <label class="checkbox">
    <input type="checkbox" name="updates" value="email">
    <span>
      Email me project updates
    </span>
  </label>
</div>

Installation

Download these files into the matching paths in your project, or use Create to assemble a kit. Include each dependency once. Do not also load app.css.

Add to your page
<link rel="stylesheet" href="/library/assets/base.css">
<link rel="stylesheet" href="/library/assets/checkbox.css">

9,894 bytes CSS including base · 0 bytes runtime JavaScript

Usage

Make the label clickable

Wrap one native checkbox and its text in label.checkbox. Keep links and other controls outside the label.

Group related choices

Use fieldset.checkbox-group and a descriptive legend. Each choice stays independent; use radio buttons for exactly one choice.

Explain validation

Connect help or errors with aria-describedby. Native required means this particular box must be checked, not any one box in a group.

Understand form values

Only checked, enabled boxes submit their name and value. A native form reset restores the initial checked state.

Use mixed state carefully

Set input.indeterminate = true in JavaScript. It describes a partial group selection; it is not a third submitted value or an HTML attribute.

Keep motion consistent

Color and checkmark opacity use the shared 300ms timing. Reduced-motion preferences and data-motion="none" disable transitions.

Building with AI? The AI Manifest has these notes and the full contract. See the AI Guide.