Skip to content

Field

A native <label> that wraps a label, a control, and an optional hint or validation message in a single accessible block.

Live example
<label class="re-field" id="field-basic">
  <span class="re-field__label">Email</span>
  <input class="re-input" type="email" name="email" id="field-basic-input" required />
  <span class="re-field__hint" id="field-basic-hint">Use your work email.</span>
</label>
Live example
<label class="re-field">
  <span class="re-field__label" data-required>Full name</span>
  <input class="re-input" type="text" name="name" required id="field-required-input" />
</label>
Live example
<label class="re-field">
  <span class="re-field__label">Password</span>
  <input
    class="re-input"
    type="password"
    name="password"
    aria-invalid="true"
    aria-describedby="field-invalid-msg"
    id="field-invalid-input"
  />
  <span id="field-invalid-msg" class="re-validation-message">
    Must be at least 8 characters.
  </span>
</label>
Live example
<div class="stack">
  <label class="re-field re-field--inline">
    <input class="re-checkbox" type="checkbox" id="field-inline-cb" />
    <span class="re-field__label">Receive marketing email</span>
  </label>
</div>

The field is a layout helper with no behavior or JavaScript of its own — keyboard and focus come entirely from the native control you wrap.

  • Keyboard — Whatever the wrapped control offers natively: Tab moves into the .re-input (or .re-checkbox / .re-radio) and Space toggles a checkbox/radio. The field adds nothing on top.
  • Focus — The control shows a visible :focus-visible ring (--re-shadow-focus); the default outline is replaced, not removed. An invalid control (below) swaps in a danger-colored ring. The wrapping <label> is not itself focusable.
  • Semantics.re-field is a native <label>, so the control it wraps inherits the label implicitly — no for/id pairing required. Mark an error message with aria-invalid="true" on the control and point aria-describedby at the .re-validation-message (as the validation example does) so assistive tech reads the message with the field. Hints work the same way: give .re-field__hint an id and reference it from the control’s aria-describedby.
  • Notes — The required asterisk from .re-field__label[data-required] is a CSS ::after glyph (visual only, not announced); always pair it with the native required attribute so the requirement is actually conveyed. Validation tones (.re-validation-message[data-tone="…"]) are carried by color and text, not by role, so don’t rely on color alone. Checkbox/radio checked states are re-established under forced-colors: active (Windows High Contrast). See the accessibility guide for the project-wide stance.