Checkbox
The Checkbox component provides an accessible way to present binary choices to users. It supports validation states, helper text, and can be grouped together for multiple selections. The component uses typography tokens for consistent text rendering and includes comprehensive keyboard support.
Basic Checkbox
Click to toggle checkbox state
You can unsubscribe at any time
Current State:
Single: Unchecked
Notifications: Enabled
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | required | Unique identifier for the checkbox |
name | string | id | Form field name |
label | string | required | Checkbox label text |
checked | boolean | false | Checked state (bindable) |
value | string | '' | Value when submitted in a form |
required | boolean | false | Whether field is required |
disabled | boolean | false | Disables the checkbox |
error | string \| null | null | Error message to display |
helper | string | - | Helper text below checkbox |
Usage Examples
Basic Checkbox
<script>
import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
let acceptTerms = $state(false);
</script>
<Checkbox
id="terms"
label="I accept the terms and conditions"
bind:checked={acceptTerms}
/> With Helper Text
<script>
import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
let subscribe = $state(false);
</script>
<Checkbox
id="newsletter"
label="Subscribe to newsletter"
bind:checked={subscribe}
helper="You can unsubscribe at any time"
/> Checkbox Group
<script>
import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
let preferences = $state({
email: true,
sms: false,
push: false
});
</script>
<fieldset>
<legend>Notification Preferences</legend>
<Checkbox
id="pref-email"
label="Email notifications"
bind:checked={preferences.email}
/>
<Checkbox
id="pref-sms"
label="SMS notifications"
bind:checked={preferences.sms}
/>
<Checkbox
id="pref-push"
label="Push notifications"
bind:checked={preferences.push}
/>
</fieldset> With Validation
<script>
import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
let agreed = $state(false);
let error = $state(null);
function validate() {
if (!agreed) {
error = 'You must agree to continue';
} else {
error = null;
}
}
</script>
<Checkbox
id="agreement"
label="I agree to the privacy policy"
bind:checked={agreed}
error={error}
required
onchange={validate}
/> Typography System
The Checkbox component uses design system typography tokens:
Applied Tokens
/* Label Text */
--typography-body-size
--typography-body-color
--typography-body-weight
/* Helper Text */
--typography-caption-size
--typography-muted-color
--typography-caption-weight
/* Error Text */
--typography-caption-size
--error (semantic color)
--typography-caption-weight Styling
Visual Design
The checkbox uses a custom appearance with:
- Size: 1.25rem (20px) square
- Border: 2px solid with theme-aware colors
- Check mark: SVG icon or CSS pseudo-element
- Border radius: Small radius for subtle rounding
States
- Unchecked: Empty box with border
- Checked: Filled with primary color and check mark
- Disabled: Reduced opacity and cursor change
- Error: Red border color with error message
- Focus: Focus ring for keyboard navigation
CSS Classes
.field-checkbox- Base checkbox styles.field-choice-label- Label container.field-error- Error state modifier.field-error-message- Error message styling.field-hint- Helper text styling
Accessibility
The Checkbox component includes comprehensive accessibility features:
ARIA Support
aria-required- Indicates required fieldsaria-invalid- Communicates error statesaria-describedby- Links helper and error textrole="alert"- Error messages announced to screen readers
Keyboard Interaction
- Space - Toggle checkbox state
- Tab - Navigate between checkboxes
- Shift+Tab - Navigate backwards
Label Association
- Clicking the label toggles the checkbox
- Proper
for/idlinking - Labels wrap the input for larger click target
Patterns
Multiple Selection
Use checkboxes when users can select multiple options:
<div class="checkbox-group">
<h3>Select features:</h3>
<Checkbox id="feat1" label="Feature A" />
<Checkbox id="feat2" label="Feature B" />
<Checkbox id="feat3" label="Feature C" />
</div> Required Fields
For required checkboxes (like terms acceptance):
<Checkbox
id="terms"
label="I accept the terms and conditions"
required
error={!accepted ? "Required" : null}
/> Indeterminate State
For parent checkboxes controlling groups:
<script>
let allSelected = $state(false);
let items = $state([false, false, false]);
$effect(() => {
const selected = items.filter(Boolean).length;
// Handle indeterminate state logic
});
</script> Best Practices
- Clear labels - Use descriptive, action-oriented labels
- Group related options - Use fieldsets for logical grouping
- Default to unchecked - Unless there’s a strong reason otherwise
- Validate on submit - Don’t show errors before interaction
- Provide context - Use helper text for complex options
- Size click targets - Ensure adequate touch/click area
Common Use Cases
- Terms acceptance - Legal agreements and policies
- Preferences - User settings and notifications
- Feature selection - Multiple choice options
- Filters - Search and listing refinements
- Bulk actions - Select multiple items for operations
Related Components
- RadioGroup - Single selection from options
- Toggle - On/off switches
- TextInput - Text entry fields
- Select - Dropdown selection