Select
Select — a single-choice dropdown, built on <select>.
Examples
<div class="field">
<label class="field-label" for="demo-country">Country</label>
<select class="select" id="demo-country" name="country" required>
<option value="" disabled selected>Choose…</option>
<option value="it">Italy</option>
<option value="ie">Ireland</option>
<option value="pt">Portugal</option>
</select>
</div>The prompt is value="" disabled selected. That is what makes required mean anything and what :user-invalid reads.
Tokens 25
Level 2, declared on .select itself. Set any of them on that selector to restyle this component without touching the skin.
| Token | Default |
|---|---|
| --select-bg | var(--color-surface-sunken) |
| --select-border-color | var(--color-border-strong) |
| --select-border-width | var(--border-width) |
| --select-color | var(--color-on-surface) |
| --select-font-family | var(--font-secondary) |
| --select-font-size | var(--font-size-sm) |
| --select-invalid-border-color | var(--color-danger) |
| --select-min-size | var(--target-size) |
| --select-padding-block | var(--space-2) |
| --select-padding-inline | var(--space-3) |
| --select-radius | var(--radius-field) |
| --select-arrow-inset | var(--space-4) |
| --select-arrow-size | 0.375rem |
| --select-arrow-glyph-size | 1rem |
| --select-arrow-icon | url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") |
| --select-check-icon | url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") |
| --select-check-size | 1rem |
| --select-option-checked-bg | var(--color-primary) |
| --select-option-checked-color | var(--color-on-primary) |
| --select-option-hover-bg | var(--color-surface-sunken) |
| --select-picker-bg | var(--color-surface-raised) |
| --select-picker-border-color | var(--color-border) |
| --select-picker-color | var(--color-on-surface) |
| --select-picker-radius | var(--radius-box) |
| --select-picker-shadow | var(--elevation-overlay) |
Variants and states
Variants
.select-lg.select-sm
State it reads
Read from the platform, never mirrored into a class that could disagree with it.
:checked:disabled:focus:hover:open:user-invaliddata-legacy
Before you ship it
What you have to do 1 requirements
- Label it, and give it a
nameso it submits. If the first option is a prompt rather than a value, write it as<option value="" disabled selected>Choose…</option>— that is what makesrequiredmean anything, and it is what:user-invalidreads. When the select is a filter, the empty first option is not a prompt but a real choice — "All regions" — and it is the only way out of the filter, for the same reason a radio group needs an "All" chip. If the options carry counts, the count goes inside the option's text:<option value="orchestra">Orchestra (115)</option>. An<option>holds text and nothing else, so there is no badge to put beside it, and any other control listing the same set has to match — write the label's shape once, in one function, and call it from all of them. Two shapes for one fact read as two facts.
src/css/components/select.css · npx mostlycss add select