Checkbox
Material Design 3 checkbox component with multiple variants, sizes, and states
Checkbox
Checkboxes allow users to select one or more items from a set or toggle a single option. @duskmoon-dev/core provides a complete set of Material Design 3 checkbox variants with support for checked, indeterminate, and disabled states.
Basic Usage
Simply add the .checkbox class to an <input type="checkbox">:
Basic Checkbox
<input type="checkbox" class="checkbox" />With Label
Wrap the checkbox in a label for better UX:
Checkbox with Label
<label class="checkbox-label">
<input type="checkbox" class="checkbox" />
<span>Accept terms and conditions</span>
</label>Checked State
Checked Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox" checked />
<span>I agree</span>
</label>Sizes
Five sizes are available:
Checkbox Sizes
<div class="flex items-center gap-4">
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-xs" checked />
<span>Extra Small</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-sm" checked />
<span>Small</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-md" checked />
<span>Medium</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-lg" checked />
<span>Large</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-xl" checked />
<span>Extra Large</span>
</label>
</div>Color Variants
Primary (Default)
Primary Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-primary" checked />
<span>Primary</span>
</label>Secondary
Secondary Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-secondary" checked />
<span>Secondary</span>
</label>Tertiary
Tertiary Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-tertiary" checked />
<span>Tertiary</span>
</label>Success
Success Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-success" checked />
<span>Success</span>
</label>Warning
Warning Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-warning" checked />
<span>Warning</span>
</label>Error
Error Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-error" checked />
<span>Error</span>
</label>Info
Info Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-info" checked />
<span>Info</span>
</label>All Colors Comparison
All Color Variants
<div class="flex flex-wrap gap-4">
<input type="checkbox" class="checkbox checkbox-primary" checked />
<input type="checkbox" class="checkbox checkbox-secondary" checked />
<input type="checkbox" class="checkbox checkbox-tertiary" checked />
<input type="checkbox" class="checkbox checkbox-success" checked />
<input type="checkbox" class="checkbox checkbox-warning" checked />
<input type="checkbox" class="checkbox checkbox-error" checked />
<input type="checkbox" class="checkbox checkbox-info" checked />
</div>States
Indeterminate
The indeterminate (mixed) state represents a partially selected state, commonly used in “select all” scenarios. Set it via JavaScript:
Indeterminate Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox" id="indeterminate-demo" />
<span>Indeterminate state</span>
</label>
<script>
document.getElementById('indeterminate-demo').indeterminate = true;
</script>Indeterminate Color Variants
All color variants support the indeterminate state:
Indeterminate Colors
<div class="flex flex-wrap gap-4">
<input type="checkbox" class="checkbox checkbox-primary" id="ind-primary" />
<input type="checkbox" class="checkbox checkbox-secondary" id="ind-secondary" />
<input type="checkbox" class="checkbox checkbox-tertiary" id="ind-tertiary" />
<input type="checkbox" class="checkbox checkbox-success" id="ind-success" />
<input type="checkbox" class="checkbox checkbox-warning" id="ind-warning" />
<input type="checkbox" class="checkbox checkbox-error" id="ind-error" />
<input type="checkbox" class="checkbox checkbox-info" id="ind-info" />
</div>
<script>
['ind-primary', 'ind-secondary', 'ind-tertiary', 'ind-success', 'ind-warning', 'ind-error', 'ind-info']
.forEach(id => document.getElementById(id).indeterminate = true);
</script>Select All Pattern
A common use case for the indeterminate state is “select all” checkboxes:
Select All Example
<div class="checkbox-group">
<label class="checkbox-label font-medium">
<input type="checkbox" class="checkbox" id="select-all" />
<span>Select All</span>
</label>
<div class="ml-6 checkbox-group">
<label class="checkbox-label">
<input type="checkbox" class="checkbox item-checkbox" checked />
<span>Item 1</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox item-checkbox" checked />
<span>Item 2</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox item-checkbox" />
<span>Item 3</span>
</label>
</div>
</div>
<script>
const selectAll = document.getElementById('select-all');
const items = document.querySelectorAll('.item-checkbox');
function updateSelectAll() {
const checkedCount = document.querySelectorAll('.item-checkbox:checked').length;
selectAll.checked = checkedCount === items.length;
selectAll.indeterminate = checkedCount > 0 && checkedCount < items.length;
}
selectAll.addEventListener('change', () => {
items.forEach(item => item.checked = selectAll.checked);
});
items.forEach(item => item.addEventListener('change', updateSelectAll));
updateSelectAll();
</script>Disabled
Disabled Checkboxes
<div class="flex gap-4">
<label class="checkbox-label">
<input type="checkbox" class="checkbox" disabled />
<span>Disabled unchecked</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" checked disabled />
<span>Disabled checked</span>
</label>
</div>Checkbox Groups
Vertical Group
Vertical Checkbox Group
<div class="checkbox-group">
<span class="checkbox-group-label">Select your interests</span>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="interests" value="design" />
<span>Design</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="interests" value="development" checked />
<span>Development</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="interests" value="marketing" />
<span>Marketing</span>
</label>
</div>Horizontal Group
Horizontal Checkbox Group
<div class="checkbox-group checkbox-group-horizontal">
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="options" value="a" checked />
<span>Option A</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="options" value="b" />
<span>Option B</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="options" value="c" />
<span>Option C</span>
</label>
</div>Form Integration
Checkbox in Form
<form class="space-y-4 max-w-md">
<div class="checkbox-group">
<span class="checkbox-group-label">Notification Preferences</span>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="email" checked />
<span>Email notifications</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="sms" />
<span>SMS notifications</span>
</label>
<label class="checkbox-label">
<input type="checkbox" class="checkbox" name="push" checked />
<span>Push notifications</span>
</label>
</div>
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-primary" required />
<span>I agree to the terms and conditions *</span>
</label>
</form>Best Practices
Accessibility
- Use semantic
<label>elements to associate labels with checkboxes - Provide clear, descriptive labels
- Use
fieldsetandlegendfor checkbox groups - Ensure sufficient color contrast
Touch Targets
The checkbox provides adequate touch targets. For mobile-first designs, use larger sizes:
Mobile-Friendly Checkbox
<label class="checkbox-label">
<input type="checkbox" class="checkbox checkbox-lg" />
<span>Mobile-friendly option</span>
</label>API Reference
Class Names
| Class | Description |
|---|---|
.checkbox | Base checkbox styling (required, on input element) |
.checkbox-xs | Extra small size (14px) |
.checkbox-sm | Small size (16px) |
.checkbox-md | Medium size (20px, default) |
.checkbox-lg | Large size (24px) |
.checkbox-xl | Extra large size (28px) |
.checkbox-primary | Primary color variant (default) |
.checkbox-secondary | Secondary color variant |
.checkbox-tertiary | Tertiary color variant |
.checkbox-success | Success color variant |
.checkbox-warning | Warning color variant |
.checkbox-error | Error color variant |
.checkbox-info | Info color variant |
.checkbox-label | Label wrapper for checkbox + text |
.checkbox-group | Container for vertical checkbox group |
.checkbox-group-horizontal | Horizontal layout modifier |
.checkbox-group-label | Group label text |
HTML Structure
Simple checkbox:
<input type="checkbox" class="checkbox" />
With label:
<label class="checkbox-label">
<input type="checkbox" class="checkbox" />
<span>Label text</span>
</label>
States
| State | How to Apply |
|---|---|
| Checked | checked attribute |
| Disabled | disabled attribute |
| Indeterminate | element.indeterminate = true (JavaScript) |
| Focus | Automatic via :focus-visible |