Field
A wrapper that groups a label, control, and helper text under one root.
Basic
Wrap a label + control pair in .field. The root is a vertical flex column with a small gap, so the label, control, and any helper text stack with a consistent rhythm. The field doesn't manage state; consumers wire for/id and aria-describedby to the control inside.
Description
Add .field__description below the control for a short hint. Pair with aria-describedby on the control so screen readers announce it.
Error
Add .field__error to surface a validation error. Pair with aria-invalid="true" on the control and tie the error to it via aria-describedby; the field paints the message in danger tone and the control inherits its own invalid border treatment.
Works with every control
The wrapper is type-agnostic. Drop in a select, textarea, slider, or any other form control and the stack stays the same.
Inline label and value
The first child of .field doesn't have to be a bare label. Drop in a row that pairs the label with a side-by-side readout (a slider value, a character counter, a unit) and the stack still flows.
Item
For input + label pairs that sit on one line (checkbox, radio, settings row), use .field__item: a flex row with a small gap and centered alignment. Inside an item, .field__label picks up the row typography (regular weight, clickable). The checkbox styling itself lands in a later batch; the row layout holds now.
Item, inline
Add .field--inline on the field root to lay items on one row with wrap. The modifier flips the root to a flex row and bumps the gap so neighbors don't crowd.
Item, reverse
Add .field__item--reverse to flip the label to the start and the input to the end. The input pins to the right edge, the common pattern for settings rows.
Item, disabled
When the input inside an item is disabled, the row dims its label and shows a not-allowed cursor on hover. The :has() selector covers .checkbox, .radio, and .switch.
Customization
These variables retune .field and its parts without touching component CSS. Override on the field, a parent scope, or :root.
| Variable | Use |
|---|---|
--field-gap | Vertical gap between label, control, and helper text |
--field-label-font-size | Label text size |
--field-label-font-weight | Label weight when stacked above a control |
--field-label-color | Label color |
--field-helper-font-size | Description and error text size |
--field-helper-color | Description color |
--field-error-color | Error message color |
--field-item-gap | Horizontal gap between input and label inside an item |
--field-item-padding-block | Vertical breathing room around an item row |
--field-item-label-font-weight | Label weight when nested inside an item |
--field-item-disabled-opacity | Label dim when the input inside an item is disabled |