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.

VariableUse
--field-gapVertical gap between label, control, and helper text
--field-label-font-sizeLabel text size
--field-label-font-weightLabel weight when stacked above a control
--field-label-colorLabel color
--field-helper-font-sizeDescription and error text size
--field-helper-colorDescription color
--field-error-colorError message color
--field-item-gapHorizontal gap between input and label inside an item
--field-item-padding-blockVertical breathing room around an item row
--field-item-label-font-weightLabel weight when nested inside an item
--field-item-disabled-opacityLabel dim when the input inside an item is disabled