Checkbox
Native checkbox and radio inputs with custom styling, semantic variants, sizes, and states. Accessible by default with proper label association.
Example
<label class="omni-checkbox">
<input type="checkbox" name="example1">
<span>Accept terms and conditions</span>
</label>
<label class="omni-checkbox">
<input type="checkbox" name="example2" checked>
<span>Subscribe to newsletter</span>
</label>
<label class="omni-checkbox">
<input type="checkbox" name="example3" disabled>
<span>Disabled option</span>
</label>
Checkboxes
Basic Checkboxes
Use the wrapper <label> pattern for proper accessibility:
Indeterminate State
JavaScript can set the indeterminate state for partial selections:
// Set indeterminate state via JavaScript
const checkbox = document.getElementById('parent-checkbox');
checkbox.indeterminate = true;
Sizes
Use data-size to adjust checkbox dimensions:
<label class="omni-checkbox" data-size="sm">
<input type="checkbox" name="size1" checked>
<span>Small checkbox</span>
</label>
<label class="omni-checkbox" data-size="lg">
<input type="checkbox" name="size3" checked>
<span>Large checkbox</span>
</label>
Required State
Required checkboxes show validation styling when unchecked:
<label class="omni-checkbox">
<input type="checkbox" name="required" required>
<span>I agree <span aria-hidden="true">*</span></span>
</label>
Readonly State
Readonly checkboxes are visible but not interactive:
Radio Buttons
Basic Radio Group
Radio buttons should be grouped with <fieldset> and <legend>:
<fieldset class="omni-radio-group">
<legend>Preferred contact method</legend>
<label class="omni-radio">
<input type="radio" name="contact" value="email" checked>
<span>Email</span>
</label>
<label class="omni-radio">
<input type="radio" name="contact" value="phone">
<span>Phone</span>
</label>
<label class="omni-radio">
<input type="radio" name="contact" value="sms">
<span>SMS</span>
</label>
</fieldset>
Radio Sizes
Use data-size on the label wrapper:
Disabled Radio
Group Layouts
Vertical Layout (Default)
Groups stack vertically by default:
Horizontal Layout
Use data-layout="horizontal" for inline groups:
<div class="omni-checkbox-group" data-layout="horizontal">
<label class="omni-checkbox">...</label>
<label class="omni-checkbox">...</label>
<label class="omni-checkbox">...</label>
</div>
Fieldset Group
Use <fieldset> for semantic grouping with legend:
<fieldset class="omni-checkbox-group">
<legend>Select your interests</legend>
<label class="omni-checkbox">...</label>
<label class="omni-checkbox">...</label>
</fieldset>
API Reference
Checkbox / Radio Classes
| Class | Element | Description |
|---|---|---|
.omni-checkbox |
<label> |
Wrapper for checkbox input |
.omni-radio |
<label> |
Wrapper for radio input |
.omni-checkbox-group |
<div> or <fieldset> |
Container for multiple checkboxes |
.omni-radio-group |
<div> or <fieldset> |
Container for multiple radio buttons |
Data Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
data-size |
sm, md, lg | md | Input size (applies to label) |
data-layout |
horizontal | — | Group layout direction (applies to group container) |
Native Input States
| Attribute | Description |
|---|---|
checked |
Input is selected |
disabled |
Input is disabled and cannot be interacted with |
required |
Input must be checked (shows validation styling) |
readonly |
Input is visible but not interactive |
indeterminate |
Set via JavaScript: checkbox.indeterminate = true |
Accessibility
- Label Association: Always wrap inputs in
<label>elements for proper association. Clicking the label toggles the input. - Keyboard Navigation: Full keyboard support (Tab, Space to toggle)
- Focus Indicators: Clear focus rings for keyboard navigation
- Radio Groups: Use
<fieldset>and<legend>to group related radio buttons semantically - Required Fields: Use native
requiredattribute for validation. Add visual asterisk witharia-hidden="true" - Validation: Browser-native validation states show danger color when required checkbox is unchecked
- Disabled State: Native
disabledattribute prevents interaction and is announced by screen readers - Readonly State: Use
readonlyattribute to display checked state without allowing changes - Color Contrast: All states meet WCAG 2.1 Level AA contrast requirements
- Indeterminate State: Provides visual feedback for partial selections in hierarchical lists
Best Practices
<!-- ✅ GOOD: Proper label association -->
<label class="omni-checkbox">
<input type="checkbox" name="agree">
<span>I agree to terms</span>
</label>
<!-- ✅ GOOD: Radio group with fieldset -->
<fieldset class="omni-radio-group">
<legend>Choose payment method</legend>
<label class="omni-radio">
<input type="radio" name="payment" value="card">
<span>Credit Card</span>
</label>
<label class="omni-radio">
<input type="radio" name="payment" value="paypal">
<span>PayPal</span>
</label>
</fieldset>
<!-- ✅ GOOD: Required with accessible asterisk -->
<label class="omni-checkbox">
<input type="checkbox" name="terms" required>
<span>I agree <span aria-hidden="true">*</span></span>
</label>
<!-- ❌ BAD: Missing label association -->
<input type="checkbox" id="bad">
<label for="bad">Checkbox</label>