Skip to content

Form Field <l-form-field>

Wraps a label, a control, and optional messages — wiring the accessibility plumbing (id/for, aria-describedby, aria-invalid, required marker) and choosing an inline or stacked layout from the control type.

HTML tag<l-form-field>
Native HTML
Progressive
Custom
Shadow DOM
Progressive Custom Element
html
<l-form-field>
  <label>I accept the terms and conditions</label>
  <input
    type="checkbox"
    required
  />
  <p class="l-hint">Read them before checking this box.</p>
  <p class="l-error">You must accept the terms to continue.</p>
</l-form-field>

Children may appear in any order — the field finds the <label>, the control (input / select / textarea), .l-hint, and .l-error by selector.

Options

Layout

Set automatically from the control: toggle controls (checkbox, radio, switch) get an inline layout (control then label); other controls stack (label above).

Read them before checking this box.

You must accept the terms to continue.

Code
html
<l-form-field>
  <label>I accept the terms and conditions</label>
  <input
    type="checkbox"
    required
  />
  <p class="l-hint">Read them before checking this box.</p>
  <p class="l-error">You must accept the terms to continue.</p>
</l-form-field>

Stacked

select, input, and textarea stack the label above the control.

Where the order will be shipped.

Code
html
<l-form-field>
  <label>Country</label>
  <select class="l-select">
    <option>United States</option>
    <option>France</option>
    <option>Japan</option>
  </select>
  <p class="l-hint">Where the order will be shipped.</p>
</l-form-field>

Required

Add native required to the control. The field reflects required and appends the marker to the label.

Hint

Add a <p class="l-hint"> for always-visible helper text. The field links it to the control with aria-describedby.

Error

Add a <p class="l-error"> for the validation message. It stays hidden until the control is invalid after interaction, then the field reveals it, sets aria-invalid, adds it to aria-describedby, and gives it role="alert" so it is announced.

Unstyled

Add unstyled to keep the accessibility wiring while opting out of auto-styling the control — useful for a third-party control or your own styling.

Accessibility

Criteria

Label association

Links <label for> to the control id, generating an id when missing

WCAG1.3.1
RGAA11.1
Description

Links .l-hint and the visible .l-error to the control via aria-describedby

WCAG1.3.1
RGAA11.10
Error identification

Sets aria-invalid and announces .l-error (role=alert) once invalid after interaction

WCAG3.3.1
RGAA11.10

API reference

Importing

css
@import 'luxen-ui/css/form-field';
js
import 'luxen-ui/form-field';

Attributes & Properties

layout'inline' | 'stacked' | undefinedProperty
Layout, derived from the control type (inline for checkbox/radio/switch, otherwise stacked). Set one to force it.
requiredbooleandefault:falseProperty
Reflected when the control is required. Drives the label marker.
optionalbooleandefault:falseProperty
Reflected when the control is not required.
invalidbooleandefault:falseProperty
Reflected once the control is invalid after interaction (or set to force the invalid state).
unstyledbooleandefault:falseProperty
Opt out of auto-styling the control; the ARIA wiring is preserved.

Slots

(default)Slot
A <label>, one form control (input / select / textarea), and optional .l-hint / .l-error message elements, in any order.

CSS classes

.l-hintClass
Helper text element. Always visible; linked via aria-describedby.
.l-errorClass
Error message element. Hidden until invalid, then revealed with role="alert" and linked via aria-describedby.