Tailwind Buttons and Forms
Buttons and forms are the two most interactive parts of any website. Buttons trigger actions. Forms collect data. Tailwind gives you the building blocks to style both beautifully without writing a single line of custom CSS.
Building Buttons with Tailwind
A Tailwind button is just a regular HTML <button> element with utility classes applied to it.
The Anatomy of a Button
<button class="bg-blue-600 text-white px-6 py-2 rounded font-semibold">
↑ ↑ ↑ ↑ ↑
Background Text Horizontal Vertical Font
color color padding padding weight
Basic Button
<button class="bg-blue-600 text-white px-6 py-2 rounded font-semibold">
Click Me
</button>Button Variants
Primary Button (filled)
<button class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded font-semibold transition">
Save Changes
</button>Secondary / Outlined Button
<button class="border-2 border-blue-600 text-blue-600 hover:bg-blue-600 hover:text-white px-6 py-2 rounded font-semibold transition">
Cancel
</button>Ghost Button (minimal)
<button class="text-blue-600 hover:underline px-4 py-2">
Learn More
</button>Danger Button
<button class="bg-red-500 hover:bg-red-600 text-white px-6 py-2 rounded font-semibold transition">
Delete
</button>Disabled Button
<button class="bg-gray-300 text-gray-500 px-6 py-2 rounded font-semibold cursor-not-allowed" disabled>
Unavailable
</button>Button Size Variants
Button Sizes Comparison: [ XS ] [ Small ] [ Medium ] [ Large ] [ XL ] px-2 px-3 px-4 px-5 px-6 py-1 py-1.5 py-2 py-2.5 py-3 text-xs text-sm text-sm text-base text-lg
<button class="px-2 py-1 text-xs bg-blue-600 text-white rounded">XS</button>
<button class="px-3 py-1.5 text-sm bg-blue-600 text-white rounded">Small</button>
<button class="px-4 py-2 text-sm bg-blue-600 text-white rounded">Medium</button>
<button class="px-5 py-2.5 text-base bg-blue-600 text-white rounded">Large</button>
<button class="px-6 py-3 text-lg bg-blue-600 text-white rounded">XL</button>Button with Icon
<button class="flex items-center gap-2 bg-green-600 text-white px-5 py-2 rounded">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path d="M5 13l4 4L19 7" stroke-width="2" stroke-linecap="round"></path>
</svg>
Approve
</button>Full-Width Button
<button class="w-full bg-blue-600 text-white py-3 rounded-lg font-bold">
Sign In
</button>Rounded Pill Button
<button class="bg-purple-600 text-white px-8 py-2 rounded-full font-semibold">
Subscribe
</button>Button Groups
<div class="flex">
<button class="bg-gray-200 text-gray-800 px-4 py-2 rounded-l border border-gray-300 hover:bg-gray-300">Left</button>
<button class="bg-gray-200 text-gray-800 px-4 py-2 border-t border-b border-gray-300 hover:bg-gray-300">Center</button>
<button class="bg-gray-200 text-gray-800 px-4 py-2 rounded-r border border-gray-300 hover:bg-gray-300">Right</button>
</div>┌──────┬────────┬───────┐ │ Left │ Center │ Right │ └──────┴────────┴───────┘ rounded rounded left only right only
Building Forms with Tailwind
Tailwind does not apply any default styles to form elements. You add every style intentionally. This gives you complete control.
The Basic Input Field Anatomy
<input class="w-full border border-gray-300 rounded p-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
↑ ↑ ↑ ↑ ↑ ↑
Full width Border Rounded Padding Remove default Blue ring
browser outline on focus
Complete Contact Form
<form class="max-w-lg mx-auto p-6 bg-white rounded-xl shadow-md space-y-4">
<h2 class="text-2xl font-bold text-gray-800">Contact Us</h2>
<!-- Text Input -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label>
<input
type="text"
placeholder="John Doe"
class="w-full border border-gray-300 rounded-lg p-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
</div>
<!-- Email Input -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input
type="email"
placeholder="john@example.com"
class="w-full border border-gray-300 rounded-lg p-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
>
</div>
<!-- Select Dropdown -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Topic</label>
<select class="w-full border border-gray-300 rounded-lg p-2.5 bg-white focus:outline-none focus:ring-2 focus:ring-blue-500">
<option>General Inquiry</option>
<option>Support</option>
<option>Billing</option>
</select>
</div>
<!-- Textarea -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Message</label>
<textarea
rows="4"
placeholder="Write your message..."
class="w-full border border-gray-300 rounded-lg p-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
></textarea>
</div>
<!-- Checkbox -->
<div class="flex items-center gap-2">
<input type="checkbox" id="agree" class="w-4 h-4 text-blue-600 rounded">
<label for="agree" class="text-sm text-gray-600">I agree to the terms</label>
</div>
<!-- Submit Button -->
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2.5 rounded-lg font-semibold transition">
Send Message
</button>
</form>Form Element Visual States
Normal State: Focus State: Error State:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Enter name │ → │■ Typing... │ │ John 123 │
└──────────────┘ └──────────────┘ └──────────────┘
border-gray-300 ring-2 ring-blue-500 border-red-500
border-transparent
+ ⚠ Invalid name format
text-red-500 text-sm
Input with Validation Error Style
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label>
<input
type="email"
class="w-full border border-red-500 rounded-lg p-2.5 focus:outline-none focus:ring-2 focus:ring-red-400 bg-red-50"
value="not-an-email"
>
<p class="mt-1 text-sm text-red-600">Please enter a valid email address.</p>
</div>Input with Icon Inside
<div class="relative">
<span class="absolute inset-y-0 left-3 flex items-center text-gray-400">🔍</span>
<input
type="text"
placeholder="Search..."
class="w-full border border-gray-300 rounded-lg py-2 pl-10 pr-4 focus:outline-none focus:ring-2 focus:ring-blue-500"
>
</div>┌─────────────────────────────┐ │ 🔍 Search... │ └─────────────────────────────┘ ↑ absolute positioned icon (left-3) input has pl-10 to avoid overlap
Radio Button Group
<fieldset>
<legend class="text-sm font-medium text-gray-700 mb-2">Choose a plan</legend>
<div class="space-y-2">
<label class="flex items-center gap-3 p-3 border rounded-lg cursor-pointer hover:bg-blue-50">
<input type="radio" name="plan" value="free" class="text-blue-600">
<span>Free Plan</span>
</label>
<label class="flex items-center gap-3 p-3 border rounded-lg cursor-pointer hover:bg-blue-50">
<input type="radio" name="plan" value="pro" class="text-blue-600">
<span>Pro Plan</span>
</label>
</div>
</fieldset>Toggle Switch (Custom Checkbox)
<label class="flex items-center cursor-pointer gap-3">
<div class="relative">
<input type="checkbox" class="sr-only peer">
<div class="w-11 h-6 bg-gray-300 rounded-full peer peer-checked:bg-blue-500 transition"></div>
<div class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow transition peer-checked:translate-x-5"></div>
</div>
<span class="text-sm text-gray-700">Enable Notifications</span>
</label>
OFF: [○ ] ON: [ ○]
gray bg blue bg
circle left circle right (translate-x-5)
Form Layout: Inline vs Stacked
Stacked (default / mobile-friendly): ┌─────────────────┐ │ Label │ │ [_____________] │ │ Label │ │ [_____________] │ └─────────────────┘ Inline (desktop search bar): ┌──────────────────────┬──────────┐ │ [________________] │ [Search] │ └──────────────────────┴──────────┘
<!-- Inline form -->
<div class="flex gap-2">
<input type="text" placeholder="Enter email..." class="flex-1 border rounded-l-lg p-2 focus:outline-none">
<button class="bg-blue-600 text-white px-4 rounded-r-lg">Subscribe</button>
</div>Summary
- Use
bg-*,text-*,px-*,py-*,rounded-*to build any button style - Use
hover:andtransitionto add smooth interactive feedback - Use
focus:ring-*andfocus:outline-nonetogether for accessible input focus styles - Use
border-red-500and error text for form validation states - Use
relative+absolutepositioning for icons inside inputs - Use
sr-onlyandpeerto build custom toggle switches
