Field
A label.field wrapper that stacks a label, any form
control, and an optional description. Works with any input type,
select, or progress.
Default
<label class="field">
<span>Email</span>
<input type="email" placeholder="you@example.com" />
<small>We'll never share your email.</small>
</label>
Required
Add required to the input and a
* appears automatically on the label.
<label class="field">
<span>Username</span>
<input type="text" placeholder="johndoe" required />
</label>
With textarea
<label class="field">
<span>Message</span>
<textarea placeholder="Write something..."></textarea>
<small>Max 500 characters.</small>
</label>
With progress
<label class="field">
<span>Uploading…</span>
<progress value="65" max="100"></progress>
<small>65%</small>
</label>
<label class="field">
<span>Processing</span>
<progress></progress>
</label>
With slider
<label class="field">
<span>Volume</span>
<input type="range" value="60" />
</label>
With checkbox
Notifications
<div class="field">
<span>Notifications</span>
<label><input type="checkbox" checked /> Email</label>
<label><input type="checkbox" /> SMS</label>
<label><input type="checkbox" /> Push</label>
</div>
With radio
Plan
You can upgrade at any time.
<div class="field">
<span>Plan</span>
<label><input type="radio" name="plan" checked /> Free</label>
<label><input type="radio" name="plan" /> Pro</label>
<label><input type="radio" name="plan" /> Enterprise</label>
<small>You can upgrade at any time.</small>
</div>
Form
<form>
<label class="field">
<span>Name</span>
<input type="text" placeholder="Evil Rabbit" required />
</label>
<label class="field">
<span>Email</span>
<input type="email" placeholder="john@example.com" required />
<small>We'll never share your email with anyone.</small>
</label>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem">
<label class="field">
<span>Phone</span>
<input type="tel" placeholder="+1 (555) 123-4567" />
</label>
<div class="field">
<span>Country</span>
<button
type="button"
class="outline"
popovertarget="country-dropdown"
style="justify-content: space-between"
>
<span>United States</span>
<svg><!-- chevron --></svg>
</button>
<div
id="country-dropdown"
popover
onchange="
document.querySelector(
`[popovertarget=${this.id}] span`,
).textContent = event.target.closest('label').textContent.trim();
this.hidePopover();
"
>
<menu>
<li>
<label
><input type="radio" name="country" value="us" checked /> United
States</label
>
</li>
<li>
<label
><input type="radio" name="country" value="uk" /> United
Kingdom</label
>
</li>
<li>
<label
><input type="radio" name="country" value="ca" /> Canada</label
>
</li>
</menu>
</div>
</div>
</div>
<label class="field">
<span>Address</span>
<input type="text" placeholder="123 Main St" />
</label>
<div>
<button class="ghost">Cancel</button>
<button>Submit</button>
</div>
</form>