Actions and feedback
Segmented control
A single choice control built from radio inputs, keyboard friendly by default.
Example
<div class="flex flex-wrap items-center gap-3"><div class="segmented" role="radiogroup" aria-label="Range">
<label class="segmented-item"><input type="radio" name="range" checked> Day</label>
<label class="segmented-item"><input type="radio" name="range"> Week</label>
<label class="segmented-item"><input type="radio" name="range"> Month</label>
<label class="segmented-item"><input type="radio" name="range" disabled> Year</label>
</div>
<div class="segmented segmented-sm mt-3" role="radiogroup" aria-label="View">
<label class="segmented-item"><input type="radio" name="view" checked><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></svg> List</label>
<label class="segmented-item"><input type="radio" name="view"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg> Grid</label>
</div>
<div class="segmented segmented-block segmented-lg mt-3" role="radiogroup" aria-label="Plan">
<label class="segmented-item"><input type="radio" name="plan"> Monthly</label>
<label class="segmented-item"><input type="radio" name="plan" checked> Yearly</label>
</div></div>Classes
8 classes. Click a name to copy it. Utilities on the same element always win over component defaults, so any of them can be adjusted with plain utility classes.
| Class | Type | What it does |
|---|---|---|
| Base | Base class of the segmented control. On a <div> in the example. Sets inline-flex display, gap, padding, corner radius, background and shadow, and 4 custom properties.CSS |
|
| Part | Part of the segmented control. On a <label> in the example. Sets alignment, inline-flex display, gap, height, padding and corner radius.CSS |
|
| Size | Extra small size. Not used in the example above. Sets --seg-h, --seg-px and --seg-fs.CSS |
|
| Size | Small size. On a <div> in the example. Sets --seg-h, --seg-px and --seg-fs.CSS |
|
| Size | Medium, the default size. Not used in the example above. Sets --seg-h, --seg-px and --seg-fs.CSS |
|
| Size | Large size. On a <div> in the example. Sets --seg-h, --seg-px and --seg-fs.CSS |
|
| Size | Extra large size. Not used in the example above. Sets --seg-h, --seg-px and --seg-fs.CSS |
|
| Modifier | Modifier, combined with the segmented class. On a <div> in the example. Sets flex display and width.CSS |
Usage
Components ship inside the same stylesheet as the utilities. There is nothing else to install and no script to load: link Monsoon and write the markup.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/monsooncss">
<!-- Segmented control: start from the base class, then add modifiers -->
<div class="flex flex-wrap items-center gap-3"><div class="segmented" role="radiogroup" aria-label="Range">
<label class="segmented-item"><input type="radio" name="range" checked> Day</label>
<label class="segmented-item"><input type="radio" name="range"> Week</label>
<label class="segmented-item"><input type="radio" name="range"> Month</label>
<label class="segmented-item"><input type="radio" name="range" disabled> Year</label>
</div>
<div class="segmented segmented-sm mt-3" role="radiogroup" aria-label="View">
<label class="segmented-item"><input type="radio" name="view" checked><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"/></svg> List</label>
<label class="segmented-item"><input type="radio" name="view"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg> Grid</label>
</div>
<div class="segmented segmented-block segmented-lg mt-3" role="radiogroup" aria-label="Plan">
<label class="segmented-item"><input type="radio" name="plan"> Monthly</label>
<label class="segmented-item"><input type="radio" name="plan" checked> Yearly</label>
</div></div>Theme it with --seed on any ancestor, for example style="--seed: #0d9488", and force a scheme with class="dark" or class="light" on a wrapper.
Accessibility
- Give every control a visible
labellinked withfor, or anaria-labelwhen the purpose is obvious from context. Link help and error text witharia-describedby; invalid styles use:user-invalid, so they appear only after the user interacts. - Checkboxes and radios stay real inputs, so they keep native keyboard behavior (Space toggles, arrow keys move within a radio group) and form submission.
- Every interactive part shows a visible focus ring with
:focus-visible, and tone colors pair with-foregroundtokens that keep text at 4.5:1 or better in light and dark mode.