Tailwind CSS Tutorial · Customizing Tailwind · Lesson 22 of 27

Styling Forms

Accessible, good-looking form inputs, selects, checkboxes and validation states with Tailwind utilities.

Create a free account to save this page, take notes and track your progress. Sign in

Inputs

Browsers style form controls differently, and Tailwind's base styles reset them, so you style them yourself. A good input has a visible label, a border, comfortable padding, and a clear focus state:

A styled formTry it yourself
<form class="max-w-sm space-y-4 p-6">
  <div>
    <label for="email" class="block text-sm font-medium text-gray-900">Email</label>
    <input id="email" type="email" placeholder="[email protected]"
           class="mt-1 block w-full rounded-lg border border-gray-300 px-3 py-2 text-gray-900 placeholder:text-gray-400 focus:border-sky-500 focus:ring-2 focus:ring-sky-500/30 focus:outline-hidden">
  </div>
  <div>
    <label for="plan" class="block text-sm font-medium text-gray-900">Plan</label>
    <select id="plan" class="mt-1 block w-full rounded-lg border border-gray-300 bg-white px-3 py-2">
      <option>Starter</option><option>Pro</option>
    </select>
  </div>
  <label class="flex items-center gap-2 text-sm"><input type="checkbox" checked class="size-4 accent-sky-600"> Send me updates</label>
  <input type="range" class="w-full accent-sky-600">
  <button class="w-full rounded-lg bg-sky-600 py-2 font-semibold text-white hover:bg-sky-500">Subscribe</button>
</form>

Checkboxes, radios and range

accent-* colours native checkboxes, radios and sliders without rebuilding them. appearance-none removes the native look when you need a fully custom control.

Validation

user-invalid: (4.1+) shows errors only after the user has interacted with a field, unlike invalid: which shows them immediately on page load. Combine with peer to reveal a message:

Validation messages with user-invalidTry it yourself
<div class="max-w-sm p-6">
  <label for="code" class="block text-sm font-medium">Coupon (letters only, then click outside)</label>
  <input id="code" pattern="[A-Za-z]+" required
         class="peer mt-1 w-full rounded-lg border border-gray-300 px-3 py-2 user-invalid:border-rose-500 user-invalid:bg-rose-50">
  <p class="mt-1 hidden text-sm text-rose-600 peer-user-invalid:block">Use letters only.</p>
</div>

For a ready-made reset of form styles there's the official @tailwindcss/forms plugin (@plugin "@tailwindcss/forms";).

Test yourself

Which class colours a native checkbox without custom markup?

  1. accent-pink-600
  2. text-pink-600
  3. bg-pink-600
  4. fill-pink-600
Show answer

Answer: accent-pink-600

accent-* sets the accent-color property used by checkboxes, radios and range inputs.

Was this page helpful?