Forms/Label

Label

Renders an accessible label associated with controls.

Themed

When to Use

Use Label when you need to:

  • Identify a form control such as an input, textarea, checkbox, or select
  • Provide a clickable target that focuses or activates the associated control
  • Improve accessibility by giving screen readers a name for form elements
  • Display required-field indicators or inline helper text alongside controls

When Not to Use

  • Standalone text that does not describe a control - use a p or heading element
  • Form layouts with built-in label handling - use Field or Form instead
  • Tooltip-style descriptions - use Tooltip for hover-revealed text
  • Badge or tag-like elements - use Badge for status indicators

Default

Label paired with a checkbox. Clicking the label toggles the checkbox.

With Input

Label associated with a text input using the htmlFor prop. Clicking the label focuses the input.

Disabled

Label automatically reduces opacity when its associated control is disabled via peer-disabled styling.

UX & Design Guidelines

Label Text

Keep labels short and descriptive - one to three words is ideal. Use sentence case (e.g., "Email address" not "Email Address"). Avoid ending labels with colons or periods. For required fields, append a visual indicator such as text-destructive asterisk rather than the word "required".

Spacing & Layout

Place labels above inputs with gap-1.5 for vertical stacks, or inline with space-x-2 for checkboxes and radios. Left-aligned labels improve scan-ability in long forms. Maintain consistent label widths in horizontal layouts to keep controls aligned.

Responsive Behavior

On mobile, labels stacked above inputs ensure the full control width is available for touch. Avoid side-by-side label-input layouts on narrow screens. The text-sm default sizing provides comfortable readability on all screen sizes without needing responsive overrides.

Color & Contrast

Labels use text-foreground by default, meeting WCAG 2.1 AA contrast requirements against bg-background and bg-card surfaces. Disabled labels reduce to 50% opacity via peer-disabled:opacity-50, maintaining the text color relationship while signaling inactivity.

Accessibility

Keyboard Navigation

  • Tab — Move focus to the associated form control (labels themselves do not receive focus)
  • Space — Toggles checkboxes and radios when their label is focused via wrapping
  • Enter — Submits the form when focus is on an input associated with a label

Screen Reader Support

  • The htmlFor attribute creates a programmatic association between the label and its control
  • Screen readers announce the label text when the associated control receives focus
  • Wrapping a control inside a label creates an implicit association without htmlFor
  • Required indicators should use aria-required="true" on the control, not just a visual asterisk

Click Target

Clicking or tapping the label focuses and activates the associated control. This is especially important for small targets like checkboxes and radio buttons, where the label provides a significantly larger hit area. Built on Radix UI Label primitive, this behavior works consistently across all browsers.

Disabled State

When the associated control is disabled, the label automatically applies peer-disabled:opacity-50 and peer-disabled:cursor-not-allowed. Group-level disabling is supported via group-data-[disabled=true] for fieldset-style containers.

ARIA Patterns

{/* Basic label association via htmlFor */}
<Label htmlFor="email">Email address</Label>
<Input id="email" type="email" />

{/* Required field with visual indicator */}
<Label htmlFor="name">
  Full Name <span className="text-destructive" aria-hidden="true">*</span>
</Label>
<Input id="name" required aria-required="true" />

{/* Label with description linked via aria-describedby */}
<Label htmlFor="bio">Bio</Label>
<Textarea id="bio" aria-describedby="bio-description" />
<p id="bio-description" className="text-xs text-muted-foreground">
  Write a short introduction about yourself.
</p>

{/* Label wrapping its control (implicit association) */}
<Label className="flex items-center gap-2">
  <Checkbox />
  I agree to the terms of service
</Label>

API Reference

The Label component accepts the following props in addition to standard label attributes. Built on @radix-ui/react-label.

PropTypeDefaultDescription
htmlForstringThe id of the form element the label is associated with. Clicking the label will focus/activate that element.
asChildbooleanfalseWhen true, the label renders its child as the root element, merging props and behavior.
classNamestringAdditional CSS classes to apply to the label.