Tailwind CSS Tutorial · Customizing Tailwind · Lesson 22 of 27
Styling Forms
Accessible, good-looking form inputs, selects, checkboxes and validation states with Tailwind utilities.
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:
<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:
<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?
accent-pink-600text-pink-600bg-pink-600fill-pink-600
Show answer
Answer: accent-pink-600
accent-* sets the accent-color property used by checkboxes, radios and range inputs.