Label
Names a form control. 14px medium on a 20px line, a flex row with an 8px gap for an icon, and it fades when its control is disabled. Source: src/components/ui/label.tsx.
Above a field
For text inputs, textareas and selects the label sits above, 8px from the control. Click the label: the input takes focus.
Beside a toggle
For checkboxes and switches the label follows the control on the same row. The whole label is a hit target, which matters for a 16px box.
Required and optional
Label has no required prop. Mark whichever case is rarer on the form: an asterisk (aria-hidden, with required on the input) or an (optional) suffix.
Disabled
Two hooks fade the label to 50%: peer-disabled when it directly follows a disabled control, and group-data-[disabled=true] from an ancestor.
Tone and icons
Colour is left to the caller. Muted works for dense table headers; caps for a group label. A leading icon gets the built-in 8px gap.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| htmlFor | string | — | The id of the control it names. Clicking the label focuses or toggles that control. |
| ...props | ComponentProps<typeof LabelPrimitive.Root> | — | A native label with Radix's double-click text-selection guard. No variants, sizes or required prop. className merges last; colour is the caller's. |
Best practices
When to use
- Every form control gets one. aria-label is the fallback only when the purpose is obvious from context (a search field with a search icon).
- Text that describes a group of controls is a fieldset legend, not a Label.
Behavior
- Above the field for text entry; after the control for checkboxes and switches.
- Keep the label visible after typing; never rely on the placeholder.
- There is no Field primitive to tie label, hint and error together; set htmlFor and aria-describedby by hand.
Accessibility
- htmlFor must match the control's id exactly; useId() keeps it unique when a form renders twice.
- A Radix Slider thumb can't be named by htmlFor; see the Slider page for the workaround.
- An asterisk alone means nothing to a screen reader: keep it aria-hidden and set required on the input.
Content
- Short nouns in sentence case, no trailing colon: Workspace name, not Workspace Name:.