Starting Point
v0.25.0
Start typing to search...
Go to Page
escClose

Field

The field wraps a form control with its label, description, and error message, and lines everything up for you. It works around any control: inputs, selects, textareas, checkboxes, switches, and more.

<form class="field-group w-full max-w-md">
  <fieldset class="field-set">
    <legend class="field-legend">Payment Method</legend>
    <p class="field-description">All transactions are secure and encrypted</p>
    <div class="field-group">
      <div class="field">
        <label class="label" for="checkout-card-name">Name on Card</label>
        <input class="input" id="checkout-card-name" placeholder="Evil Rabbit" required />
      </div>
      <div class="field">
        <label class="label" for="checkout-card-number">Card Number</label>
        <input class="input" id="checkout-card-number" placeholder="1234 5678 9012 3456" required />
        <p class="field-description">Enter your 16-digit card number</p>
      </div>
      <div class="grid grid-cols-3 gap-4">
        <div class="field">
          <label class="label" for="checkout-exp-month">Month</label>
          <select class="select" id="checkout-exp-month">
            <option value="">MM</option>
            <option>01</option>
            <option>02</option>
            <option>03</option>
            <option>04</option>
            <option>05</option>
            <option>06</option>
            <option>07</option>
            <option>08</option>
            <option>09</option>
            <option>10</option>
            <option>11</option>
            <option>12</option>
          </select>
        </div>
        <div class="field">
          <label class="label" for="checkout-exp-year">Year</label>
          <select class="select" id="checkout-exp-year">
            <option value="">YYYY</option>
            <option>2024</option>
            <option>2025</option>
            <option>2026</option>
            <option>2027</option>
            <option>2028</option>
            <option>2029</option>
          </select>
        </div>
        <div class="field">
          <label class="label" for="checkout-cvv">CVV</label>
          <input class="input" id="checkout-cvv" placeholder="123" required />
        </div>
      </div>
    </div>
  </fieldset>
  <div class="field-separator"></div>
  <fieldset class="field-set">
    <legend class="field-legend">Billing Address</legend>
    <p class="field-description">
      The billing address associated with your payment method
    </p>
    <div class="field-group">
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="checkout-same-as-shipping" checked />
        <label class="label font-normal" for="checkout-same-as-shipping">
          Same as shipping address
        </label>
      </div>
    </div>
  </fieldset>
  <fieldset class="field-set">
    <div class="field-group">
      <div class="field">
        <label class="label" for="checkout-comments">Comments</label>
        <textarea class="textarea resize-none" id="checkout-comments" placeholder="Add any additional comments"></textarea>
      </div>
    </div>
  </fieldset>
  <div class="field field-horizontal">
    <button type="submit" class="btn">Submit</button>
    <button type="button" class="btn btn-outline">Cancel</button>
  </div>
</form>

Usage

Add the field class to a wrapper and put the label, control, and supporting text inside. Fields stack vertically by default; group several with field-group.

ClassDescription
fieldAdd to the wrapper around a label, control, and supporting text
field-horizontal field-responsiveAdd to field to lay it out in a row, always or from the md container size
field-contentAdd to a block holding a title and description inside a field
field-titleAdd to a heading inside field-content
field-descriptionAdd to a paragraph with supporting text
field-errorAdd to a paragraph with a validation message
field-groupAdd to a container stacking several fields
field-setAdd to a <fieldset> wrapping related fields
field-legendAdd to the <legend> of a field set
field-legend-labelAdd to field-legend for a label-sized legend
field-separatorAdd to a divider between fields; put text in a <span> inside
<div class="field">
  <label class="label" for="my-input">Label</label>
  <input class="input" id="my-input" />
  <p class="field-description">Description</p>
</div>

Examples

Input

Stack the label, control, and description in any order; the field spaces them consistently.

<fieldset class="field-set">
  <div class="field-group">
    <div class="field">
      <label class="label" for="field-username">Username</label>
      <input class="input" id="field-username" type="text" placeholder="Max Leiter" />
      <p class="field-description">Choose a unique username for your account.</p>
    </div>
    <div class="field">
      <label class="label" for="field-password">Password</label>
      <p class="field-description">Must be at least 8 characters long.</p>
      <input class="input" id="field-password" type="password" placeholder="••••••••" />
    </div>
  </div>
</fieldset>

Textarea

A textarea fields like any other control.

<fieldset class="field-set">
  <div class="field-group">
    <div class="field">
      <label class="label" for="field-feedback">Feedback</label>
      <textarea class="textarea" id="field-feedback" rows="4" placeholder="Your feedback helps us improve..."></textarea>
      <p class="field-description">Share your thoughts about our service.</p>
    </div>
  </div>
</fieldset>

Select

A select with a label and supporting text.

<div class="field">
  <label class="label" for="field-department">Department</label>
  <select class="select" id="field-department">
    <option value="">Choose department</option>
    <option>Engineering</option>
    <option>Design</option>
    <option>Marketing</option>
    <option>Sales</option>
    <option>Customer Support</option>
    <option>Human Resources</option>
    <option>Finance</option>
    <option>Operations</option>
  </select>
  <p class="field-description">Select your department or area of work.</p>
</div>

Slider

Fields also wrap controls without a <label> element, like a slider titled with a field-title.

<div class="field">
  <span class="field-title">Budget</span>
  <p class="field-description">
    Set your maximum budget ($<span class="font-medium tabular-nums" data-sp-slider-value="field-budget">500</span>).
  </p>
  <input type="range" class="slider mt-2" id="field-budget" min="0" max="1000" step="10" value="500" style="--val: 50%" aria-label="Maximum budget" />
</div>

Fieldset

Group related fields in a field-set with a field-legend so they are announced together.

<fieldset class="field-set">
  <legend class="field-legend">Address Information</legend>
  <p class="field-description">We need your address to deliver your order.</p>
  <div class="field-group">
    <div class="field">
      <label class="label" for="field-street">Street Address</label>
      <input class="input" id="field-street" type="text" placeholder="123 Main St" />
    </div>
    <div class="grid grid-cols-2 gap-4">
      <div class="field">
        <label class="label" for="field-city">City</label>
        <input class="input" id="field-city" type="text" placeholder="New York" />
      </div>
      <div class="field">
        <label class="label" for="field-zip">Postal Code</label>
        <input class="input" id="field-zip" type="text" placeholder="90502" />
      </div>
    </div>
  </div>
</fieldset>

Checkbox

Horizontal fields lay out checkboxes, with a field-separator dividing sections.

<div class="field-group">
  <fieldset class="field-set">
    <legend class="field-legend field-legend-label">Show these items on the desktop</legend>
    <p class="field-description">Select the items you want to show on the desktop.</p>
    <div class="field-group gap-3">
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="finder-pref-hard-disks" />
        <label class="label font-normal" for="finder-pref-hard-disks">Hard disks</label>
      </div>
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="finder-pref-external-disks" />
        <label class="label font-normal" for="finder-pref-external-disks">External disks</label>
      </div>
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="finder-pref-cds-dvds" />
        <label class="label font-normal" for="finder-pref-cds-dvds">CDs, DVDs, and iPods</label>
      </div>
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="finder-pref-connected-servers" />
        <label class="label font-normal" for="finder-pref-connected-servers">Connected servers</label>
      </div>
    </div>
  </fieldset>
  <div class="field-separator"></div>
  <div class="field field-horizontal">
    <input type="checkbox" class="checkbox" id="finder-pref-sync-folders" checked />
    <div class="field-content">
      <label class="label" for="finder-pref-sync-folders">Sync Desktop &amp; Documents folders</label>
      <p class="field-description">
        Your Desktop &amp; Documents folders are being synced with iCloud
        Drive. You can access them from other devices.
      </p>
    </div>
  </div>
</div>

Radio

A radio group in a field set, one horizontal field per option.

<fieldset class="field-set">
  <legend class="field-legend field-legend-label">Subscription Plan</legend>
  <p class="field-description">Yearly and lifetime plans offer significant savings.</p>
  <div class="field-group gap-3">
    <div class="field field-horizontal">
      <input type="radio" class="radio" id="plan-monthly" name="plan" checked />
      <label class="label font-normal" for="plan-monthly">Monthly ($9.99/month)</label>
    </div>
    <div class="field field-horizontal">
      <input type="radio" class="radio" id="plan-yearly" name="plan" />
      <label class="label font-normal" for="plan-yearly">Yearly ($99.99/year)</label>
    </div>
    <div class="field field-horizontal">
      <input type="radio" class="radio" id="plan-lifetime" name="plan" />
      <label class="label font-normal" for="plan-lifetime">Lifetime ($299.99)</label>
    </div>
  </div>
</fieldset>

Switch

A horizontal field puts a switch beside its label.

<div class="field field-horizontal">
  <input type="checkbox" role="switch" class="switch" id="field-2fa" />
  <label class="label" for="field-2fa">Multi-factor authentication</label>
</div>

Choice card

Wrap a horizontal field in a label and the whole card becomes clickable, tinting itself while checked.

<div class="field-group">
  <fieldset class="field-set">
    <legend class="field-legend field-legend-label">Compute Environment</legend>
    <p class="field-description">Select the compute environment for your cluster.</p>
    <div class="field-group gap-3">
      <label class="label">
        <div class="field field-horizontal">
          <div class="field-content">
            <span class="field-title">Kubernetes</span>
            <p class="field-description">Run GPU workloads on a K8s cluster.</p>
          </div>
          <input type="radio" class="radio" name="field-compute" checked />
        </div>
      </label>
      <label class="label">
        <div class="field field-horizontal">
          <div class="field-content">
            <span class="field-title">Virtual Machine</span>
            <p class="field-description">Access a cluster to run GPU workloads.</p>
          </div>
          <input type="radio" class="radio" name="field-compute" />
        </div>
      </label>
    </div>
  </fieldset>
</div>

Field group

Stack sections of fields with a field-group and divide them with separators.

<div class="field-group">
  <fieldset class="field-set">
    <legend class="field-legend field-legend-label">Responses</legend>
    <p class="field-description">
      Get notified when ChatGPT responds to requests that take time, like
      research or image generation.
    </p>
    <div class="field-group gap-3">
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="notif-push" checked disabled />
        <label class="label font-normal" for="notif-push">Push notifications</label>
      </div>
    </div>
  </fieldset>
  <div class="field-separator"></div>
  <fieldset class="field-set">
    <legend class="field-legend field-legend-label">Tasks</legend>
    <p class="field-description">
      Get notified when tasks you've created have updates.
      <a href="#">Manage tasks</a>
    </p>
    <div class="field-group gap-3">
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="notif-push-tasks" />
        <label class="label font-normal" for="notif-push-tasks">Push notifications</label>
      </div>
      <div class="field field-horizontal">
        <input type="checkbox" class="checkbox" id="notif-email-tasks" />
        <label class="label font-normal" for="notif-email-tasks">Email notifications</label>
      </div>
    </div>
  </fieldset>
</div>

Responsive

Add field-responsive and the field stacks on narrow containers and becomes a row from the md container size. Resize the preview to see it switch.

<form class="w-full max-w-lg">
  <fieldset class="field-set">
    <legend class="field-legend">Profile</legend>
    <p class="field-description">Fill in your profile information.</p>
    <div class="field-group">
      <div class="field field-responsive">
        <div class="field-content">
          <label class="label" for="field-resp-name">Name</label>
          <p class="field-description">Provide your full name for identification</p>
        </div>
        <input class="input" id="field-resp-name" placeholder="Evil Rabbit" required />
      </div>
      <div class="field field-responsive">
        <button type="submit" class="btn">Submit</button>
        <button type="button" class="btn btn-outline">Cancel</button>
      </div>
    </div>
  </fieldset>
</form>

Invalid

Set aria-invalid on the control for the error ring and put the message in a field-error.

<div class="field">
  <label class="label" for="field-invalid-email">Email</label>
  <input class="input" id="field-invalid-email" type="email" value="not-an-email" aria-invalid="true" />
  <p class="field-error">Enter a valid email address.</p>
</div>