shadcn-html / label
Built with: CSS
Label
Renders an accessible label associated with form controls. Built on the native <label> element
with :has() for focus-reactive styling. No JavaScript required.
Default
Basic label paired with an input. Click the label to focus the input.
<label class="label" for="email">Email</label>
<input class="input" type="email" id="email" placeholder="you@example.com">
Required
Required indicator using a red asterisk.
<label class="label" for="name">
Name <span aria-hidden="true" class="text-destructive">*</span>
</label>
<input class="input" type="text" id="name" required>
Optional hint
Hint text indicating the field is optional.
<label class="label" for="bio">
Bio <span class="label-hint">(optional)</span>
</label>
Disabled
Dimmed label for disabled fields. The label auto-detects the disabled input via :has() — no data-disabled attribute needed.
<label class="label" for="disabled">Disabled field</label>
<input class="input" type="text" id="disabled" disabled>
With Checkbox
Inline label paired with a checkbox control.
<div class="checkbox-item">
<input class="checkbox" type="checkbox" id="terms">
<label class="label" for="terms" style="margin:0;">Accept terms and conditions</label>
</div>
With Switch
Inline label paired with a switch control.
<div class="switch-item">
<input class="switch" type="checkbox" role="switch" id="airplane">
<label class="label" for="airplane" style="margin:0;">Airplane Mode</label>
</div>
Form Field
Label composed with an input and description text, as used in forms.
This is your public display name.
<div>
<label class="label" for="username">Username</label>
<input class="input" type="text" id="username" placeholder="shadcn">
<p class="field-description">This is your public display name.</p>
</div>
CSS view file
/* -- Label component -------------------------------------------- */
@layer components {
.label {
font-size: 0.875rem;
font-weight: 500;
font-family: var(--font-sans);
line-height: 1;
color: var(--foreground);
display: block;
margin-bottom: 0.375rem;
cursor: default;
/* Disabled — explicit attribute */
&[data-disabled] {
opacity: 0.7;
cursor: not-allowed;
}
/* Disabled — auto-detect via adjacent disabled control */
&:has(+ :disabled),
&:has(+ [data-disabled]) {
opacity: 0.7;
cursor: not-allowed;
}
}
/* -- Hint text (optional, required indicators) ----------- */
.label-hint {
font-weight: 400;
font-size: 0.8125rem;
color: var(--muted-foreground);
}
/* -- Accessibility ---------------------------------------- */
@media (prefers-contrast: more) {
.label[data-disabled],
.label:has(+ :disabled),
.label:has(+ [data-disabled]) {
opacity: 0.85;
}
}
@media (forced-colors: active) {
.label {
color: LinkText;
}
.label[data-disabled],
.label:has(+ :disabled),
.label:has(+ [data-disabled]) {
opacity: 1;
color: GrayText;
}
}
}