Radio
Native radio input with custom styling. Works with semantic fieldsets and supports sizes and variants. Always use within a group for mutually exclusive selections.
Example
<fieldset>
<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="mail">
<span>Mail</span>
</label>
</fieldset>
Variants
Sizes
Use data-size on the label to adjust radio dimensions:
<label class="omni-radio" data-size="sm">
<input type="radio" name="size" value="1">
<span>Small size</span>
</label>
<label class="omni-radio">
<input type="radio" name="size" value="2">
<span>Default size</span>
</label>
<label class="omni-radio" data-size="lg">
<input type="radio" name="size" value="3">
<span>Large size</span>
</label>
States
Disabled
<label class="omni-radio">
<input type="radio" name="option" value="1" disabled>
<span>Disabled option</span>
</label>
Required
Required radios show validation states. The browser will prevent form submission if no option is selected:
<fieldset>
<legend>Choose a plan <span aria-hidden="true">*</span></legend>
<label class="omni-radio">
<input type="radio" name="plan" value="basic" required>
<span>Basic</span>
</label>
<label class="omni-radio">
<input type="radio" name="plan" value="pro" required>
<span>Pro</span>
</label>
</fieldset>
Readonly
Readonly radios are visible but not interactive:
<label class="omni-radio">
<input type="radio" name="plan" value="pro" checked readonly>
<span>Pro (selected, locked)</span>
</label>
Group Layouts
Vertical (default)
Radio groups are vertical by default:
<fieldset class="omni-radio-group">
<legend>Shipping method</legend>
<label class="omni-radio">
<input type="radio" name="shipping" value="standard" checked>
<span>Standard (5-7 days)</span>
</label>
<label class="omni-radio">
<input type="radio" name="shipping" value="express">
<span>Express (2-3 days)</span>
</label>
<label class="omni-radio">
<input type="radio" name="shipping" value="overnight">
<span>Overnight</span>
</label>
</fieldset>
Horizontal
Use data-layout="horizontal" on the group container for inline layout:
<fieldset class="omni-radio-group" data-layout="horizontal">
<legend>Size</legend>
<label class="omni-radio">
<input type="radio" name="size" value="small">
<span>Small</span>
</label>
<label class="omni-radio">
<input type="radio" name="size" value="medium" checked>
<span>Medium</span>
</label>
<label class="omni-radio">
<input type="radio" name="size" value="large">
<span>Large</span>
</label>
</fieldset>
API Reference
Label Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
data-size |
sm, md, lg | md | Radio button size |
Input Attributes
| Attribute | Type | Description |
|---|---|---|
name |
string | Required. Groups related radios together (all radios in a group must share the same name) |
value |
string | Required. The value submitted when this radio is selected |
checked |
boolean | Marks this radio as selected by default |
disabled |
boolean | Prevents interaction with this radio |
required |
boolean | Requires one radio in the group to be selected before form submission |
readonly |
boolean | Makes the radio visible but not interactive |
Group Container Attributes
| Attribute | Values | Default | Description |
|---|---|---|---|
data-layout |
horizontal | vertical | Layout direction for radio group |
Accessibility
- Always wrap radio groups in a
<fieldset>with a<legend>to provide context - Each radio must have an associated
<label>using the wrapper pattern - All radios in a group must share the same
nameattribute - Full keyboard navigation: Tab to enter group, arrow keys to select options, Space to check
- Focus visible indicators with clear contrast
- Disabled state prevents interaction and conveys state visually with reduced opacity
- Required validation shows red border when no option is selected
- Readonly state makes radios visible but non-interactive (useful for locked selections)
- Native browser behavior ensures proper announcements to screen readers
- Use
aria-hidden="true"on decorative asterisks for required fields
Best Practices
- Use radios when users must select exactly one option from a set
- For 2-5 options, consider horizontal layout for better visual grouping
- For 6+ options, stick with vertical layout for easier scanning
- If no default selection is appropriate, don't use
checkedon any option - Use descriptive labels that clearly communicate what each option means
- Group related radios with semantic
<fieldset>and<legend>
Components Used
Other OmniUI components demonstrated on this page: