Field
Field
<form>
<div role="group" aria-label="Checkout fields" class="fieldset">
<fieldset class="fieldset">
<legend>Payment Method</legend>
<p>All transactions are secure and encrypted</p>
<div role="group" aria-label="Payment method fields">
<div role="group" class="field">
<label for="checkout-card-name">Name on Card</label>
<input id="checkout-card-name" type="text" placeholder="Evil Rabbit" required />
</div>
<div role="group" class="field">
<label for="checkout-card-number">Card Number</label>
<input id="checkout-card-number" type="text" placeholder="1234 5678 9012 3456" aria-describedby="checkout-card-number-description" required />
<p id="checkout-card-number-description">Enter your 16-digit card number</p>
</div>
<div class="grid grid-cols-3 gap-4">
<div role="group" class="field">
<label for="checkout-exp-month">Month</label>
<select id="checkout-exp-month" class="select w-full">
<option value="">MM</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
</div>
<div role="group" class="field">
<label for="checkout-exp-year">Year</label>
<select id="checkout-exp-year" class="select w-full">
<option value="">YYYY</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
<option value="2027">2027</option>
<option value="2028">2028</option>
<option value="2029">2029</option>
</select>
</div>
<div role="group" class="field">
<label for="checkout-cvv">CVV</label>
<input id="checkout-cvv" type="text" placeholder="123" required />
</div>
</div>
</div>
</fieldset>
<div class="field-separator">
<hr role="separator" />
</div>
<fieldset class="fieldset">
<legend>Billing Address</legend>
<p>The billing address associated with your payment method</p>
<div role="group" class="field" data-orientation="horizontal">
<input id="checkout-same-as-shipping" type="checkbox" checked />
<label for="checkout-same-as-shipping" class="font-normal">Same as shipping address</label>
</div>
</fieldset>
<fieldset class="fieldset">
<div role="group" class="field">
<label for="checkout-comments">Comments</label>
<textarea id="checkout-comments" placeholder="Add any additional comments" rows="3"></textarea>
</div>
</fieldset>
<div role="group" class="field" data-orientation="horizontal">
<button type="submit" class="btn">Submit</button>
<button type="button" class="btn" data-variant="outline">Cancel</button>
</div>
</div>
</form> Usage
Include CSS
Import Tailwind and one full Basecoat style bundle.
@import "tailwindcss";
@import "basecoat-css/vega.css";Or import only the base CSS, Field component CSS, and one style pack.
@import "tailwindcss";
@import "basecoat-css/base.css";
@import "basecoat-css/components/field.css";
@import "basecoat-css/styles/vega.css";Using CDN or bundler imports? See the Installation page.
Add your field HTML
Use class="field" for one control and class="fieldset" for related controls. Use a native <fieldset> when the group needs a <legend>; otherwise use a labelled role="group".
<fieldset class="fieldset">
<legend>Profile</legend>
<p>This appears on invoices and emails.</p>
<div role="group" aria-label="Profile fields">
<div role="group" class="field">
<label for="name">Full name</label>
<input id="name" autocomplete="off" placeholder="Evil Rabbit" />
<p>This appears on invoices and emails.</p>
</div>
<div role="group" class="field" data-invalid>
<label for="username">Username</label>
<input id="username" autocomplete="off" aria-invalid="true" aria-describedby="username-error" />
<p id="username-error" role="alert">Choose another username.</p>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="newsletter" type="checkbox" role="switch" />
<label for="newsletter">Subscribe to the newsletter</label>
</div>
</div>
</fieldset> HTML structure
<fieldset class=“fieldset”>- Native group for related fields. Use
<legend>for the label and a following<p>for description. <div role=“group” class=“fieldset”>- Structural group when
<fieldset>is not appropriate. Addaria-labeloraria-labelledby. <div role=“group” class=“field”>- Single field wrapper. Add
data-orientationwhen needed. <label>- Label for the control. Use
forwhen the control has anid. <input>,<select>,<textarea>- Native form control. Put
aria-invalid=“true”on the invalid control, not only on the wrapper. <section>- Optional content wrapper for label and description when the control sits beside text.
<p>- Helper text or error text. Use
role=“alert”for validation errors and connect it witharia-describedby.
Examples
Input
<fieldset class="fieldset">
<div role="group" aria-label="Account credentials">
<div role="group" class="field">
<label for="username">Username</label>
<input id="username" type="text" placeholder="Max Leiter" aria-describedby="username-description" />
<p id="username-description">Choose a unique username for your account.</p>
</div>
<div role="group" class="field">
<label for="password">Password</label>
<p id="password-description">Must be at least 8 characters long.</p>
<input id="password" type="password" placeholder="••••••••" aria-describedby="password-description" />
</div>
</div>
</fieldset> Textarea
<fieldset class="fieldset">
<div role="group" class="field">
<label for="feedback">Feedback</label>
<textarea id="feedback" placeholder="Your feedback helps us improve..." rows="4" aria-describedby="feedback-description"></textarea>
<p id="feedback-description">Share your thoughts about our service.</p>
</div>
</fieldset> Select
Select your department or area of work.
<div role="group" class="field">
<label for="department">Department</label>
<select id="department" class="select w-full" aria-describedby="department-description">
<option value="">Choose department</option>
<option value="engineering">Engineering</option>
<option value="design">Design</option>
<option value="marketing">Marketing</option>
<option value="sales">Sales</option>
<option value="support">Customer Support</option>
<option value="hr">Human Resources</option>
<option value="finance">Finance</option>
<option value="operations">Operations</option>
</select>
<p id="department-description">Select your department or area of work.</p>
</div> Slider
Set your maximum budget (up to $800).
<div role="group" class="field">
<label for="price-range">Price Range</label>
<p id="price-range-description">Set your maximum budget <span id="price-range-output">(up to $800)</span>.</p>
<input id="price-range" type="range" min="0" max="1000" step="10" value="800" aria-describedby="price-range-description" class="input" />
</div> Fieldset
<fieldset class="fieldset">
<legend>Address Information</legend>
<p>We need your address to deliver your order.</p>
<div role="group" aria-label="Address fields">
<div role="group" class="field">
<label for="street">Street Address</label>
<input id="street" type="text" placeholder="123 Main St" />
</div>
<div class="grid grid-cols-2 gap-4">
<div role="group" class="field">
<label for="city">City</label>
<input id="city" type="text" placeholder="New York" />
</div>
<div role="group" class="field">
<label for="zip">Postal Code</label>
<input id="zip" type="text" placeholder="90502" />
</div>
</div>
</div>
</fieldset> Checkbox
Your Desktop & Documents folders are being synced with iCloud Drive. You can access them from other devices.
<div role="group" aria-label="Finder preferences" class="fieldset">
<fieldset class="fieldset">
<legend data-variant="label">Show these items on the desktop</legend>
<p>Select the items you want to show on the desktop.</p>
<div role="group" aria-label="Desktop items">
<div role="group" class="field" data-orientation="horizontal">
<input id="finder-hard-disks" type="checkbox" />
<label for="finder-hard-disks" class="font-normal">Hard disks</label>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="finder-external-disks" type="checkbox" />
<label for="finder-external-disks" class="font-normal">External disks</label>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="finder-cds" type="checkbox" />
<label for="finder-cds" class="font-normal">CDs, DVDs, and iPods</label>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="finder-connected-servers" type="checkbox" />
<label for="finder-connected-servers" class="font-normal">Connected servers</label>
</div>
</div>
</fieldset>
<div class="field-separator">
<hr role="separator" />
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="sync-folders" type="checkbox" checked />
<section>
<label for="sync-folders">Sync Desktop & Documents folders</label>
<p>Your Desktop & Documents folders are being synced with iCloud Drive. You can access them from other devices.</p>
</section>
</div>
</div> Radio
<fieldset class="fieldset">
<legend data-variant="label">Subscription Plan</legend>
<p>Yearly and lifetime plans offer significant savings.</p>
<div role="radiogroup" aria-label="Subscription plan">
<div role="group" class="field" data-orientation="horizontal">
<input id="plan-monthly" type="radio" name="plan" value="monthly" checked />
<label for="plan-monthly" class="font-normal">Monthly ($9.99/month)</label>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="plan-yearly" type="radio" name="plan" value="yearly" />
<label for="plan-yearly" class="font-normal">Yearly ($99.99/year)</label>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="plan-lifetime" type="radio" name="plan" value="lifetime" />
<label for="plan-lifetime" class="font-normal">Lifetime ($299.99)</label>
</div>
</div>
</fieldset> Switch
Enable multi-factor authentication. If you do not have a two-factor device, you can use a one-time code sent to your email.
<div role="group" class="field" data-orientation="horizontal">
<section>
<label for="multi-factor-authentication">Multi-factor authentication</label>
<p>Enable multi-factor authentication. If you do not have a two-factor device, you can use a one-time code sent to your email.</p>
</section>
<input id="multi-factor-authentication" type="checkbox" role="switch" />
</div> Choice card
Wrap a .field inside a <label> to create selectable field cards. This works with radio, checkbox, and switch controls.
<fieldset class="fieldset">
<legend data-variant="label">Compute Environment</legend>
<p>Select the compute environment for your cluster.</p>
<div role="radiogroup" aria-label="Compute environment">
<label for="compute-kubernetes">
<div role="group" class="field" data-orientation="horizontal">
<section>
<h3>Kubernetes</h3>
<p>Run GPU workloads on a K8s cluster.</p>
</section>
<input id="compute-kubernetes" type="radio" name="compute" value="kubernetes" checked />
</div>
</label>
<label for="compute-vm">
<div role="group" class="field" data-orientation="horizontal">
<section>
<h3>Virtual Machine</h3>
<p>Access a cluster to run GPU workloads.</p>
</section>
<input id="compute-vm" type="radio" name="compute" value="vm" />
</div>
</label>
</div>
</fieldset> Field group
Stack fields inside a group and use .field-separator to divide sections.
<div role="group" aria-label="Notification preferences" class="fieldset">
<fieldset class="fieldset">
<legend data-variant="label">Responses</legend>
<p>Get notified when ChatGPT responds to requests that take time, like research or image generation.</p>
<div role="group" aria-label="Response notifications">
<div role="group" class="field" data-orientation="horizontal" data-disabled="true">
<input id="push-responses" type="checkbox" checked disabled />
<label for="push-responses" class="font-normal">Push notifications</label>
</div>
</div>
</fieldset>
<div class="field-separator">
<hr role="separator" />
</div>
<fieldset class="fieldset">
<legend data-variant="label">Tasks</legend>
<p>Get notified when tasks you've created have updates. <a href="#">Manage tasks</a></p>
<div role="group" aria-label="Task notifications">
<div role="group" class="field" data-orientation="horizontal">
<input id="push-tasks" type="checkbox" />
<label for="push-tasks" class="font-normal">Push notifications</label>
</div>
<div role="group" class="field" data-orientation="horizontal">
<input id="email-tasks" type="checkbox" />
<label for="email-tasks" class="font-normal">Email notifications</label>
</div>
</div>
</fieldset>
</div> Responsive layout
Use data-orientation="responsive" to stack by default and switch to horizontal in wider containers.
<form>
<fieldset class="fieldset">
<legend>Profile</legend>
<p>Fill in your profile information.</p>
<div class="field-separator">
<hr role="separator" />
</div>
<div role="group" aria-label="Profile fields">
<div role="group" class="field" data-orientation="responsive">
<section>
<label for="responsive-name">Name</label>
<p id="responsive-name-description">Provide your full name for identification</p>
</section>
<input id="responsive-name" placeholder="Evil Rabbit" aria-describedby="responsive-name-description" required />
</div>
<div class="field-separator">
<hr role="separator" />
</div>
<div role="group" class="field" data-orientation="responsive">
<section>
<label for="responsive-message">Message</label>
<p id="responsive-message-description">You can write your message here. Keep it short, preferably under 100 characters.</p>
</section>
<textarea id="responsive-message" placeholder="Hello, world!" rows="4" aria-describedby="responsive-message-description" required class="min-h-[100px] resize-none sm:min-w-[300px]"></textarea>
</div>
<div class="field-separator">
<hr role="separator" />
</div>
<div role="group" class="field" data-orientation="responsive">
<button type="submit" class="btn">Submit</button>
<button type="button" class="btn" data-variant="outline">Cancel</button>
</div>
</div>
</fieldset>
</form> Validation and errors
Add data-invalid to .field and aria-invalid="true" to the invalid control.
Enter a valid email address.
<div role="group" class="field" data-invalid>
<label for="invalid-email">Email</label>
<input id="invalid-email" type="email" value="wrong-email" aria-invalid="true" aria-describedby="invalid-email-error" />
<p id="invalid-email-error" role="alert">Enter a valid email address.</p>
</div> RTL
Add dir="rtl" to the field, fieldset, or an ancestor.
<fieldset class="fieldset" dir="rtl">
<legend>الملف الشخصي</legend>
<p>تظهر هذه المعلومات في حسابك.</p>
<div role="group" aria-label="حقول الملف الشخصي">
<div role="group" class="field">
<label for="field-rtl-name">الاسم الكامل</label>
<input id="field-rtl-name" type="text" placeholder="أرنب شرير" />
<p>اكتب اسمك الأول والأخير.</p>
</div>
</div>
</fieldset>