HomeCSS Tailwind
Chapter 5

05 — Components & Patterns

Button Variants

<!-- Primary -->
<button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
  Primary
</button>
 
<!-- Secondary -->
<button class="px-4 py-2 bg-slate-200 text-slate-900 rounded hover:bg-slate-300 transition-colors">
  Secondary
</button>
 
<!-- Outline -->
<button class="px-4 py-2 border border-slate-300 text-slate-700 rounded hover:bg-slate-50 transition-colors">
  Outline
</button>
 
<!-- Ghost -->
<button class="px-4 py-2 text-slate-700 hover:bg-slate-100 rounded transition-colors">
  Ghost
</button>
 
<!-- Danger -->
<button class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors">
  Danger
</button>
 
<!-- Disabled -->
<button class="px-4 py-2 bg-slate-300 text-slate-500 rounded cursor-not-allowed" disabled>
  Disabled
</button>
 
<!-- With Icon -->
<button class="px-4 py-2 bg-blue-500 text-white rounded flex items-center gap-2 hover:bg-blue-600">
  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
  </svg>
  Add Item
</button>

Form Inputs

Text Input

<div class="space-y-2">
  <label class="block text-sm font-medium text-slate-700" for="email">
    Email
  </label>
  <input 
    type="email" 
    id="email"
    class="w-full px-3 py-2 border border-slate-300 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition"
    placeholder="you@example.com"
  >
  <p class="text-sm text-red-600">Error message</p>
</div>

Input with Icon

<div class="relative">
  <div class="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400">
    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
    </svg>
  </div>
  <input 
    type="search"
    class="w-full pl-10 pr-4 py-2 border border-slate-300 rounded focus:ring-2 focus:ring-blue-500"
    placeholder="Search..."
  >
</div>

Select

<select class="w-full px-3 py-2 border border-slate-300 rounded focus:ring-2 focus:ring-blue-500">
  <option>Option 1</option>
  <option>Option 2</option>
  <option>Option 3</option>
</select>

Checkbox

<label class="flex items-center gap-2 cursor-pointer">
  <input type="checkbox" class="w-4 h-4 rounded border-slate-300 text-blue-500 focus:ring-blue-500">
  <span class="text-sm">Remember me</span>
</label>

Radio

<label class="flex items-center gap-2 cursor-pointer">
  <input type="radio" name="option" class="w-4 h-4 border-slate-300 text-blue-500 focus:ring-blue-500">
  <span class="text-sm">Option A</span>
</label>

Cards

Basic Card

<div class="bg-white rounded-lg shadow border border-slate-200 overflow-hidden">
  <img src="/image.jpg" alt="Card image" class="w-full h-48 object-cover">
  <div class="p-6">
    <h3 class="text-lg font-semibold text-slate-900 mb-2">Card Title</h3>
    <p class="text-slate-600 mb-4">Card description goes here with some details.</p>
    <button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
      Action
    </button>
  </div>
</div>

Interactive Card (Hover)

<div class="bg-white rounded-lg shadow border border-slate-200 overflow-hidden transition-all hover:shadow-lg hover:-translate-y-1">
  <div class="p-6">
    <h3 class="font-semibold">Interactive Card</h3>
  </div>
</div>

Card with Badge

<div class="bg-white rounded-lg shadow border relative">
  <span class="absolute top-4 right-4 bg-red-500 text-white text-xs px-2 py-1 rounded">
    New
  </span>
  <div class="p-6">
    <h3 class="font-semibold">Card with Badge</h3>
  </div>
</div>

Navigation

Horizontal Navigation

<nav class="bg-slate-800">
  <div class="max-w-7xl mx-auto px-4">
    <div class="flex gap-6">
      <a href="/" class="py-4 px-3 text-white hover:text-slate-300 border-b-2 border-transparent hover:border-blue-500">
        Home
      </a>
      <a href="/about" class="py-4 px-3 text-slate-300 hover:text-white border-b-2 border-transparent hover:border-blue-500">
        About
      </a>
      <a href="/contact" class="py-4 px-3 text-slate-300 hover:text-white border-b-2 border-transparent hover:border-blue-500">
        Contact
      </a>
    </div>
  </div>
</nav>

Sidebar Navigation

<nav class="w-64 bg-slate-800 text-white h-screen">
  <div class="p-4">
    <div class="font-bold text-xl mb-6">Menu</div>
    <ul class="space-y-2">
      <li>
        <a href="/" class="flex items-center gap-3 px-3 py-2 rounded bg-slate-700">
          <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path>
          </svg>
          Dashboard
        </a>
      </li>
      <li>
        <a href="/users" class="flex items-center gap-3 px-3 py-2 rounded hover:bg-slate-700">
          <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"></path>
          </svg>
          Users
        </a>
      </li>
    </ul>
  </div>
</nav>

Breadcrumb

<nav class="text-sm">
  <ol class="flex items-center gap-2 text-slate-600">
    <li><a href="/" class="hover:text-slate-900">Home</a></li>
    <li>/</li>
    <li><a href="/products" class="hover:text-slate-900">Products</a></li>
    <li>/</li>
    <li class="text-slate-900">Laptop</li>
  </ol>
</nav>

Alerts / Toasts

Alert Banner

<div class="bg-blue-50 border-l-4 border-blue-500 p-4">
  <div class="flex">
    <div class="flex-shrink-0">
      <svg class="w-5 h-5 text-blue-400" fill="currentColor" viewBox="0 0 20 20">
        <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"></path>
      </svg>
    </div>
    <div class="ml-3">
      <p class="text-sm text-blue-700">Information message here.</p>
    </div>
  </div>
</div>

Toast Notification

<div class="fixed bottom-4 right-4 bg-slate-900 text-white px-6 py-3 rounded-lg shadow-lg">
  <div class="flex items-center gap-3">
    <span>Success! Item saved.</span>
    <button class="hover:text-slate-300"></button>
  </div>
</div>

Modals

Simple Modal

<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4">
  <div class="bg-white rounded-lg max-w-md w-full max-h-[90vh] overflow-y-auto">
    <div class="p-6">
      <h3 class="text-lg font-semibold mb-4">Modal Title</h3>
      <p class="text-slate-600 mb-6">Modal content goes here.</p>
      <div class="flex justify-end gap-3">
        <button class="px-4 py-2 text-slate-700 hover:bg-slate-100 rounded">Cancel</button>
        <button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">Confirm</button>
      </div>
    </div>
  </div>
</div>

Tables

<div class="overflow-x-auto">
  <table class="w-full text-left">
    <thead class="bg-slate-50 border-b">
      <tr>
        <th class="px-4 py-3 font-semibold text-slate-900">Name</th>
        <th class="px-4 py-3 font-semibold text-slate-900">Email</th>
        <th class="px-4 py-3 font-semibold text-slate-900">Role</th>
        <th class="px-4 py-3 font-semibold text-slate-900">Status</th>
        <th class="px-4 py-3 font-semibold text-slate-900">Actions</th>
      </tr>
    </thead>
    <tbody class="divide-y">
      <tr class="hover:bg-slate-50">
        <td class="px-4 py-3">Alice Johnson</td>
        <td class="px-4 py-3">alice@example.com</td>
        <td class="px-4 py-3">Admin</td>
        <td class="px-4 py-3">
          <span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded-full">Active</span>
        </td>
        <td class="px-4 py-3">
          <button class="text-blue-600 hover:text-blue-800 mr-2">Edit</button>
          <button class="text-red-600 hover:text-red-800">Delete</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Badges

<span class="px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 rounded-full">New</span>
<span class="px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded-full">Success</span>
<span class="px-2 py-1 text-xs font-medium bg-red-100 text-red-800 rounded-full">Error</span>
<span class="px-2 py-1 text-xs font-medium bg-slate-100 text-slate-800 rounded-full">Pending</span>
 
<!-- Pill badge -->
<span class="px-3 py-1 text-sm bg-slate-200 text-slate-800 rounded-full">12</span>

Key Takeaways

  • Buttons: Use consistent padding, rounded corners, hover states, focus rings
  • Forms: Labels required, focus states, error messages, proper spacing
  • Cards: Shadow + rounded corners, hover effects for interactivity
  • Navigation: Clear active states, consistent spacing
  • Modals: Backdrop overlay, centered content, clear actions
  • Tables: Striped rows or hover states, overflow handling on mobile
  • Accessibility: Focus rings, semantic HTML, ARIA labels where needed