Web Development

Tailwind CSS: Utility-First CSS Framework

Tutorial lengkap belajar Tailwind CSS dari nol — konsep utility-first, responsive design, flexbox & grid, dark mode, custom config, dan membuat komponen praktis dengan contoh kode

1. Pengenalan Tailwind CSS

Tailwind CSS adalah framework CSS utility-first yang memungkinkan Anda membangun desain yang cepat dan responsif langsung di HTML — tanpa perlu menulis CSS kustom. Dikembangkan oleh Adam Wathan, Tailwind telah menjadi salah satu framework CSS paling populer di dunia pengembangan web modern.

Berbeda dengan framework CSS tradisional seperti Bootstrap yang menyediakan komponen siap pakai, Tailwind menyediakan class-class kecil yang bisa dikombinasikan untuk membuat desain yang sepenuhnya unik.

Tailwind CSS vs Framework Lain

Aspek Tailwind CSS Bootstrap CSS Murni
PendekatanUtility-firstComponent-basedManual
Keunikan Desain🟢 Sangat fleksibel🟡 Terlihat "Bootstrap"🟢 Bebas total
Kecepatan Develop🟢 Sangat cepat🟢 Cepat🔴 Lambat
Ukuran CSS🟢 Kecil (purging)🟡 Sedang🟢 Sesuai kode
Learning Curve🟡 Perlu hafal class🟢 Mudah🟡 Perlu CSS expert
Kustomisasi🟢 Tinggi (config)🟡 Sedang🟢 Total

Instalasi Tailwind CSS

Bash — Instalasi
# Instalasi dengan Vite (paling umum)
npm create vite@latest project-saya -- --template vanilla
cd project-saya

# Instal Tailwind CSS
npm install -D tailwindcss @tailwindcss/vite

# Tambahkan plugin ke vite.config.js
# import tailwindcss from '@tailwindcss/vite'
# plugins: [tailwindcss()]

# Tambahkan di src/style.css:
# @import "tailwindcss";

# Jalankan development server
npm run dev

# Untuk proyek yang sudah ada (tanpa Vite):
npm install -D tailwindcss
npx tailwindcss init

# Dengan Next.js:
npx create-next-app@latest --tailwind my-app
Diagram: Perbandingan CSS Approaches
┌───────────────────────────────────────────────────────┐
│          PERBANDINGAN PENDEKATAN CSS                   │
│                                                       │
│  1. CSS Murni:                                        │
│     HTML: <button class="btn-primary">               │
│     CSS:  .btn-primary {                              │
│            padding: 8px 16px;                          │
│            background: blue;                           │
│            color: white;                               │
│            border-radius: 4px;                         │
│          }                                            │
│                                                       │
│  2. Bootstrap:                                        │
│     HTML: <button class="btn btn-primary">           │
│     CSS:  (terdefinisi di framework)                  │
│                                                       │
│  3. Tailwind CSS:                                     │
│     HTML: <button class="px-4 py-2 bg-blue-500       │
│               text-white rounded">                    │
│     CSS:  (tidak perlu menulis CSS sama sekali!)      │
│                                                       │
│  Tailwind = tulis desain langsung di HTML             │
│  dengan class utility yang kecil-kecil                │
└───────────────────────────────────────────────────────┘

2. Konsep Utility-First

Pendekatan utility-first berarti setiap class CSS di Tailwind mewakili satu properti CSS saja. Misalnya, text-center sama dengan text-align: center, dan p-4 sama dengan padding: 1rem.

Utility Dasar: Spacing, Warna, Typography

HTML — Utility Classes
<!-- SPACING (padding & margin) -->
<!-- p-1 = 0.25rem (4px), p-2 = 0.5rem (8px), p-4 = 1rem (16px) -->
<!-- m-1 = 0.25rem, m-2 = 0.5rem, m-4 = 1rem -->
<!-- px-4 = padding kiri-kanan, py-2 = padding atas-bawah -->
<!-- mt-4 = margin-top, mb-2 = margin-bottom -->
<div class="p-4 m-2">Box dengan padding 16px dan margin 8px</div>
<div class="px-6 py-3">Padding horizontal 24px, vertical 12px</div>
<div class="mt-8 mb-4">Margin top 32px, bottom 16px</div>

<!-- WARNA (background & text) -->
<!-- Format: bg-{warna}-{tingkat} atau text-{warna}-{tingkat} -->
<!-- Tingkat: 50 (teringan) sampai 950 (tergelap) -->
<div class="bg-blue-500 text-white">Latar biru, teks putih</div>
<div class="bg-gray-100 text-gray-800">Latar abu muda, teks gelap</div>
<div class="bg-green-600 text-green-50">Latar hijau tua, teks hijau muda</div>
<div class="bg-red-100 text-red-700">Latar merah muda, teks merah tua</div>

<!-- TYPOGRAPHY -->
<!-- text-{ukuran}: text-xs, text-sm, text-base, text-lg, text-xl, text-2xl, dst -->
<!-- font-{ketebalan}: font-light, font-normal, font-medium, font-semibold, font-bold -->
<p class="text-lg font-semibold">Teks besar dan tebal</p>
<p class="text-sm text-gray-500">Teks kecil dan abu-abu</p>
<p class="text-xl font-bold text-blue-600">Judul biru besar</p>
<p class="text-center">Teks rata tengah</p>
<p class="text-left">Teks rata kiri</p>
<p class="text-right">Teks rata kanan</p>

<!-- BORDERS & ROUNDED -->
<div class="border border-gray-300 rounded-lg">
  Box dengan border dan sudut bulat
</div>
<div class="border-2 border-blue-500 rounded-full">
  Border tebal biru, sudut bulat penuh
</div>
<div class="rounded-none">Tanpa sudut bulat</div>
<div class="rounded-sm">Sudut bulat kecil</div>
<div class="rounded-xl">Sudut bulat besar</div>

<!-- SHADOWS -->
<div class="shadow-sm">Bayangan kecil</div>
<div class="shadow-md">Bayangan sedang</div>
<div class="shadow-lg">Bayangan besar</div>
<div class="shadow-xl">Bayangan sangat besar</div>
<div class="shadow-2xl">Bayangan ekstra besar</div>

Hover, Focus, dan State Lainnya

HTML — State Modifiers
<!-- Hover: prefix hover: -->
<button class="bg-blue-500 hover:bg-blue-700 text-white px-4 py-2 rounded">
  Hover Saya
</button>

<!-- Focus: prefix focus: -->
<input class="border border-gray-300 focus:border-blue-500 focus:ring-2
              focus:ring-blue-200 px-3 py-2 rounded outline-none"
       placeholder="Klik untuk fokus">

<!-- Active: prefix active: -->
<button class="bg-gray-200 active:bg-gray-400 px-4 py-2 rounded">
  Klik dan Tahan
</button>

<!-- Disabled: prefix disabled: -->
<button class="bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed
              text-white px-4 py-2 rounded" disabled>
  Tombol Nonaktif
</button>

<!-- Group Hover (hover parent affect child) -->
<div class="group p-4 border rounded hover:bg-blue-50">
  <h3 class="text-lg group-hover:text-blue-600">Judul</h3>
  <p class="text-gray-500 group-hover:text-gray-700">Deskripsi</p>
</div>

<!-- Kombinasi state -->
<button class="bg-blue-500 hover:bg-blue-600 focus:ring-2 focus:ring-blue-300
              active:bg-blue-700 text-white px-6 py-2 rounded-lg
              transition-colors duration-200">
  Tombol dengan Multiple States
</button>
💡 Tips

Tailwind mendukung hover, focus, active, disabled, first, last, odd, even, dan banyak modifier lainnya. Cukup tambahkan prefix sebelum class utility. Anda juga bisa menggabungkan beberapa modifier: sm:hover:bg-blue-500.

3. Responsive Design

Tailwind menggunakan mobile-first approach — class tanpa prefix berlaku untuk semua ukuran layar, dan class dengan prefix breakpoint berlaku untuk layar yang lebih besar. Ini memudahkan pembuatan desain responsif.

Breakpoint

Prefix Min Width Keterangan
(tanpa prefix)0pxMobile (default)
sm:640pxTablet kecil
md:768pxTablet / iPad
lg:1024pxLaptop
xl:1280pxDesktop
2xl:1536pxMonitor besar

Contoh Responsive Layout

HTML — Responsive
<!-- Layout responsif: 1 kolom di mobile, 2 di tablet, 3 di desktop -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 p-4">
  <div class="bg-white p-4 rounded shadow">Kartu 1</div>
  <div class="bg-white p-4 rounded shadow">Kartu 2</div>
  <div class="bg-white p-4 rounded shadow">Kartu 3</div>
</div>

<!-- Font size responsif -->
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl font-bold">
  Judul yang Menyesuaikan Layar
</h1>

<!-- Padding responsif -->
<div class="px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16">
  Konten dengan padding yang bertambah di layar besar
</div>

<!-- Sembunyikan/Perlihatkan elemen -->
<!-- hidden = display:none, block = display:block -->
<div class="block md:hidden">Hanya terlihat di mobile</div>
<div class="hidden md:block">Hanya terlihat di tablet ke atas</div>
<div class="hidden lg:block">Hanya terlihat di laptop ke atas</div>

<!-- Navbar responsif -->
<nav class="flex flex-col sm:flex-row justify-between items-center p-4">
  <a href="/" class="text-xl font-bold">Logo</a>
  <ul class="flex flex-col sm:flex-row gap-2 sm:gap-4">
    <li><a href="/" class="hover:text-blue-500">Beranda</a></li>
    <li><a href="/about" class="hover:text-blue-500">Tentang</a></li>
    <li><a href="/blog" class="hover:text-blue-500">Blog</a></li>
  </ul>
</nav>

<!-- Card responsif -->
<div class="max-w-sm md:max-w-md lg:max-w-lg mx-auto p-4">
  <div class="bg-white rounded-lg shadow-lg overflow-hidden">
    <img src="foto.jpg" alt="Foto" class="w-full h-48 object-cover">
    <div class="p-4 md:p-6">
      <h3 class="text-lg md:text-xl font-semibold">Judul Kartu</h3>
      <p class="text-sm md:text-base text-gray-600 mt-2">
        Deskripsi kartu yang panjang dan informatif.
      </p>
    </div>
  </div>
</div>
Diagram: Responsive Breakpoints
┌──────────────────────────────────────────────────────────┐
│                    RESPONSIVE BREAKPOINTS                 │
│                                                          │
│  Mobile      Tablet      Laptop      Desktop      Ultra  │
│  <640px     640-767     768-1023    1024-1279    1536+   │
│                                                          │
│  ┌────────┐ ┌────────┐ ┌─────────┐ ┌──────────┐ ┌─────┐ │
│  │  1     │ │  2 kol │ │  3 kol  │ │  4 kol   │ │ 4kol│ │
│  │ kolom  │ │  om    │ │  om     │ │  om      │ │     │ │
│  └────────┘ └────────┘ └─────────┘ └──────────┘ └─────┘ │
│                                                          │
│  class=""   sm:         md:         lg:          2xl:     │
│                                                          │
│  Contoh:                                                 │
│  grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4          │
│  → 1 kolom mobile, 2 tablet, 4 desktop                   │
└──────────────────────────────────────────────────────────┘

4. Flexbox & Grid

Tailwind menyediakan utility class lengkap untuk Flexbox dan CSS Grid, dua metode layout paling kuat di CSS modern. Keduanya memudahkan membuat layout yang kompleks tanpa perlu menulis CSS manual.

Flexbox

HTML — Flexbox
<!-- Flex dasar -->
<div class="flex">
  <div class="p-4 bg-blue-200">Item 1</div>
  <div class="p-4 bg-blue-300">Item 2</div>
  <div class="p-4 bg-blue-400">Item 3</div>
</div>

<!-- Flex dengan justify dan align -->
<!-- justify-*: horizontal alignment (main axis) -->
<!-- items-*: vertical alignment (cross axis) -->
<div class="flex justify-center items-center h-64 bg-gray-100">
  <p class="text-lg">Tengah secara horizontal dan vertikal</p>
</div>

<!-- Space between (navigasi) -->
<div class="flex justify-between items-center p-4 bg-white shadow">
  <span class="font-bold text-xl">Logo</span>
  <nav class="flex gap-4">
    <a href="#">Beranda</a>
    <a href="#">Produk</a>
    <a href="#">Kontak</a>
  </nav>
</div>

<!-- Flex wrap (item berpindah baris) -->
<div class="flex flex-wrap gap-2">
  <span class="px-3 py-1 bg-blue-100 rounded-full">Tag 1</span>
  <span class="px-3 py-1 bg-green-100 rounded-full">Tag 2</span>
  <span class="px-3 py-1 bg-red-100 rounded-full">Tag 3</span>
  <span class="px-3 py-1 bg-yellow-100 rounded-full">Tag 4</span>
  <span class="px-3 py-1 bg-purple-100 rounded-full">Tag 5</span>
</div>

<!-- Flex direction column -->
<div class="flex flex-col gap-4 p-4">
  <div class="p-4 bg-white rounded shadow">Item Atas</div>
  <div class="p-4 bg-white rounded shadow">Item Tengah</div>
  <div class="p-4 bg-white rounded shadow">Item Bawah</div>
</div>

<!-- Flex grow dan shrink -->
<div class="flex gap-4">
  <div class="w-32 p-4 bg-blue-200">Fixed 128px</div>
  <div class="flex-1 p-4 bg-blue-300">Sisa ruang (grow)</div>
  <div class="w-32 p-4 bg-blue-200">Fixed 128px</div>
</div>

CSS Grid

HTML — CSS Grid
<!-- Grid dasar: 3 kolom sama besar -->
<div class="grid grid-cols-3 gap-4">
  <div class="p-4 bg-blue-100">1</div>
  <div class="p-4 bg-blue-200">2</div>
  <div class="p-4 bg-blue-300">3</div>
  <div class="p-4 bg-blue-100">4</div>
  <div class="p-4 bg-blue-200">5</div>
  <div class="p-4 bg-blue-300">6</div>
</div>

<!-- Grid dengan kolom yang berbeda ukuran -->
<!-- grid-cols-4 = 4 kolom, col-span-2 = lebar 2 kolom -->
<div class="grid grid-cols-4 gap-4">
  <div class="col-span-2 p-4 bg-blue-500 text-white">Header (2 kolom)</div>
  <div class="p-4 bg-gray-100">Sidebar</div>
  <div class="p-4 bg-gray-100">Iklan</div>
  <div class="col-span-3 p-4 bg-blue-100">Konten Utama (3 kolom)</div>
  <div class="p-4 bg-gray-100">Sidebar Kanan</div>
</div>

<!-- Grid responsive -->
<!-- 1 kolom di mobile, 2 di tablet, 4 di desktop -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
  <div class="bg-white p-6 rounded-lg shadow">
    <h3 class="font-bold">Fitur 1</h3>
    <p class="text-gray-600">Deskripsi fitur 1</p>
  </div>
  <div class="bg-white p-6 rounded-lg shadow">
    <h3 class="font-bold">Fitur 2</h3>
    <p class="text-gray-600">Deskripsi fitur 2</p>
  </div>
  <div class="bg-white p-6 rounded-lg shadow">
    <h3 class="font-bold">Fitur 3</h3>
    <p class="text-gray-600">Deskripsi fitur 3</p>
  </div>
  <div class="bg-white p-6 rounded-lg shadow">
    <h3 class="font-bold">Fitur 4</h3>
    <p class="text-gray-600">Deskripsi fitur 4</p>
  </div>
</div>

<!-- Template areas dengan grid -->
<div class="grid grid-cols-4 grid-rows-3 gap-4 h-96">
  <div class="col-span-4 bg-blue-500 text-white p-4 flex items-center">
    Navbar
  </div>
  <div class="col-span-1 row-span-2 bg-gray-200 p-4">Sidebar</div>
  <div class="col-span-3 bg-white p-4">Konten Utama</div>
  <div class="col-span-3 bg-gray-100 p-4">Footer Konten</div>
  <div class="col-span-4 bg-gray-800 text-white p-4 flex items-center">
    Footer
  </div>
</div>
⚠️ Flexbox vs Grid: Kapan Menggunakan?

Gunakan Flexbox untuk layout satu dimensi (baris ATAU kolom) — navigasi, toolbar, card row. Gunakan Grid untuk layout dua dimensi (baris DAN kolom) — halaman utama, dashboard, image gallery. Keduanya bisa digabungkan dalam satu halaman!

5. Dark Mode

Tailwind CSS memiliki dukungan dark mode built-in. Cukup tambahkan prefix dark: sebelum class utility, dan class tersebut hanya aktif saat dark mode diaktifkan.

Cara Mengaktifkan Dark Mode

HTML — Dark Mode
<!-- Tambahkan class "dark" di <html> untuk mengaktifkan -->
<html class="dark">
  <body>...</body>
</html>

<!-- Contoh halaman dengan dark mode -->
<div class="bg-white dark:bg-gray-900 min-h-screen">
  <h1 class="text-gray-900 dark:text-white text-2xl font-bold">
    Judul yang Menyesuaikan Tema
  </h1>

  <p class="text-gray-600 dark:text-gray-300">
    Paragraf ini berwarna gelap di light mode dan terang di dark mode.
  </p>

  <div class="bg-gray-100 dark:bg-gray-800 p-4 rounded-lg">
    <h2 class="text-gray-800 dark:text-gray-100 font-semibold">
      Kartu Informasi
    </h2>
    <p class="text-gray-500 dark:text-gray-400">
      Konten kartu yang adaptif dengan tema.
    </p>
  </div>

  <button class="bg-blue-500 dark:bg-blue-600 text-white
                 hover:bg-blue-600 dark:hover:bg-blue-700
                 px-4 py-2 rounded">
    Tombol Adaptif
  </button>

  <input class="bg-white dark:bg-gray-800
                 border border-gray-300 dark:border-gray-600
                 text-gray-900 dark:text-white
                 focus:ring-blue-500 dark:focus:ring-blue-400
                 px-3 py-2 rounded"
         placeholder="Input adaptif">
</div>

Toggle Dark Mode dengan JavaScript

JavaScript — Toggle Dark Mode
// Toggle dark mode dan simpan preferensi di localStorage
function toggleDarkMode() {
  const html = document.documentElement;
  const isDark = html.classList.toggle('dark');

  // Simpan preferensi
  localStorage.setItem('theme', isDark ? 'dark' : 'light');

  // Update icon tombol
  document.getElementById('themeIcon').textContent = isDark ? '🌙' : '☀️';
}

// Saat halaman dimuat, cek preferensi tersimpan
function initTheme() {
  const savedTheme = localStorage.getItem('theme');
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

  if (savedTheme === 'dark' || (!savedTheme && prefersDark)) {
    document.documentElement.classList.add('dark');
  }
}

// Jalankan saat halaman dimuat
initTheme();
💡 Strategi Dark Mode

Tailwind mendukung dua strategi dark mode: class strategy (default, Anda kontrol manual dengan class dark di HTML) dan media strategy (mengikuti preferensi sistem operasi user). Class strategy lebih fleksibel karena user bisa toggle kapan saja. Atur di tailwind.config.js: darkMode: 'class'.

6. Custom Configuration

Tailwind sangat bisa dikustomisasi melalui file konfigurasi tailwind.config.js. Anda bisa menambahkan warna, font, spacing, breakpoint, dan banyak lagi sesuai kebutuhan proyek.

File Konfigurasi

JavaScript — tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],

  // Dark mode strategy
  darkMode: 'class',

  theme: {
    // EXTEND: menambahkan (tidak menghapus yang ada)
    extend: {
      // Custom colors
      colors: {
        primary: {
          50: '#eff6ff',
          100: '#dbeafe',
          200: '#bfdbfe',
          300: '#93c5fd',
          400: '#60a5fa',
          500: '#3b82f6',
          600: '#2563eb',
          700: '#1d4ed8',
          800: '#1e40af',
          900: '#1e3a8a',
        },
        brand: '#ff6b35',
        accent: '#004e89',
      },

      // Custom font family
      fontFamily: {
        sans: ['Inter', 'system-ui', 'sans-serif'],
        display: ['Poppins', 'sans-serif'],
        mono: ['JetBrains Mono', 'monospace'],
      },

      // Custom spacing
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },

      // Custom breakpoints
      screens: {
        'xs': '475px',
        '3xl': '1920px',
      },

      // Custom animations
      animation: {
        'fade-in': 'fadeIn 0.5s ease-in-out',
        'slide-up': 'slideUp 0.3s ease-out',
        'bounce-slow': 'bounce 3s infinite',
      },
      keyframes: {
        fadeIn: {
          '0%': { opacity: '0' },
          '100%': { opacity: '1' },
        },
        slideUp: {
          '0%': { transform: 'translateY(20px)', opacity: '0' },
          '100%': { transform: 'translateY(0)', opacity: '1' },
        },
      },
    },
  },

  plugins: [
    // Contoh: require('@tailwindcss/typography'),
    // Contoh: require('@tailwindcss/forms'),
  ],
};

Menggunakan Custom Config

HTML — Custom Classes
<!-- Custom colors -->
<div class="bg-primary-500 text-white">Warna primary custom</div>
<div class="bg-brand text-white">Warna brand custom</div>
<button class="bg-accent hover:bg-accent/80 text-white px-4 py-2">
  Tombol Accent
</button>

<!-- Custom fonts -->
<h1 class="font-display text-3xl">Judul dengan font Poppins</h1>
<p class="font-sans">Teks dengan font Inter</p>
<code class="font-mono bg-gray-100 px-2 py-1 rounded">Kode monospace</code>

<!-- Custom animations -->
<div class="animate-fade-in">Fade in saat muncul</div>
<div class="animate-slide-up">Slide up animation</div>
<div class="animate-bounce-slow">Bounce pelan</div>

<!-- Custom spacing -->
<div class="w-128 h-144 p-4">Box dengan ukuran custom</div>

<!-- Custom breakpoint -->
<div class="xs:block hidden">Terlihat di 475px ke atas</div>
<div class="3xl:text-6xl text-4xl">Teks ekstra besar di 3XL</div>

7. Membuat Komponen dengan Tailwind

Berikut adalah beberapa contoh komponen UI yang umum digunakan, dibangun sepenuhnya dengan Tailwind CSS tanpa CSS kustom.

Kartu Produk

HTML — Card Component
<!-- Kartu Produk E-Commerce -->
<div class="max-w-sm bg-white dark:bg-gray-800 rounded-xl shadow-lg
            overflow-hidden hover:shadow-xl transition-shadow duration-300">
  <div class="relative">
    <img src="produk.jpg" alt="Produk"
         class="w-full h-48 object-cover">
    <span class="absolute top-2 right-2 bg-red-500 text-white
                  text-xs font-bold px-2 py-1 rounded-full">
      -30%
    </span>
  </div>
  <div class="p-5">
    <div class="flex items-center gap-1 mb-2">
      <span class="text-yellow-400">★★★★☆</span>
      <span class="text-sm text-gray-500">(128 ulasan)</span>
    </div>
    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">
      Nama Produk Premium
    </h3>
    <p class="text-sm text-gray-500 dark:text-gray-400 mt-1">
      Deskripsi singkat produk yang menarik perhatian.
    </p>
    <div class="flex items-center justify-between mt-4">
      <div>
        <span class="text-2xl font-bold text-blue-600">Rp 299.000</span>
        <span class="text-sm text-gray-400 line-through ml-2">
          Rp 429.000
        </span>
      </div>
      <button class="bg-blue-500 hover:bg-blue-600 text-white
                     px-4 py-2 rounded-lg transition-colors">
        🛒 Beli
      </button>
    </div>
  </div>
</div>

Form Login

HTML — Login Form
<!-- Form Login Modern -->
<div class="min-h-screen flex items-center justify-center
            bg-gray-50 dark:bg-gray-900 px-4">
  <div class="w-full max-w-md">
    <div class="bg-white dark:bg-gray-800 rounded-2xl shadow-xl p-8">
      <div class="text-center mb-8">
        <h1 class="text-3xl font-bold text-gray-900 dark:text-white">
          Masuk
        </h1>
        <p class="text-gray-500 dark:text-gray-400 mt-2">
          Selamat datang kembali!
        </p>
      </div>

      <form class="space-y-5">
        <div>
          <label class="block text-sm font-medium text-gray-700
                        dark:text-gray-300 mb-1">Email</label>
          <input type="email" placeholder="email@contoh.com"
                 class="w-full px-4 py-3 border border-gray-300
                        dark:border-gray-600 rounded-lg
                        bg-white dark:bg-gray-700
                        text-gray-900 dark:text-white
                        focus:ring-2 focus:ring-blue-500
                        focus:border-transparent outline-none
                        transition-all">
        </div>

        <div>
          <label class="block text-sm font-medium text-gray-700
                        dark:text-gray-300 mb-1">Password</label>
          <input type="password" placeholder="••••••••"
                 class="w-full px-4 py-3 border border-gray-300
                        dark:border-gray-600 rounded-lg
                        bg-white dark:bg-gray-700
                        text-gray-900 dark:text-white
                        focus:ring-2 focus:ring-blue-500
                        focus:border-transparent outline-none
                        transition-all">
        </div>

        <div class="flex items-center justify-between">
          <label class="flex items-center gap-2">
            <input type="checkbox"
                   class="w-4 h-4 text-blue-500 rounded">
            <span class="text-sm text-gray-600
                         dark:text-gray-400">Ingat saya</span>
          </label>
          <a href="#" class="text-sm text-blue-500 hover:underline">
            Lupa password?
          </a>
        </div>

        <button type="submit"
                class="w-full bg-blue-500 hover:bg-blue-600
                       text-white font-semibold py-3 rounded-lg
                       transition-colors duration-200">
          Masuk
        </button>
      </form>

      <p class="text-center text-sm text-gray-500 mt-6">
        Belum punya akun?
        <a href="#" class="text-blue-500 hover:underline font-medium">
          Daftar sekarang
        </a>
      </p>
    </div>
  </div>
</div>
💡 Tips: Mengurangi Duplikasi Class

Jika Anda sering mengulang kombinasi class yang sama, gunakan fitur @apply di file CSS untuk membuat class custom. Namun, di proyek React/Vue, lebih baik buat komponen reusable daripada mengandalkan @apply. Dengan begitu, styling tetap dekat dengan logika komponen.

8. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Tailwind CSS:

Pertanyaan 1: Apa arti pendekatan "utility-first" dalam Tailwind CSS?

a) Menulis semua style dalam satu file CSS besar
b) Menggunakan class-class kecil yang masing-masing mewakili satu properti CSS
c) Menggunakan komponen siap pakai seperti Bootstrap
d) Tidak perlu menulis HTML sama sekali

Pertanyaan 2: Apa prefix untuk breakpoint tablet (min-width: 768px) di Tailwind?

a) sm:
b) md:
c) lg:
d) xl:

Pertanyaan 3: Bagaimana cara mengaktifkan dark mode class di Tailwind?

a) Tambahkan class "dark" di elemen <html>
b) Gunakan prefix "night:" di setiap class
c) Import file CSS dark-mode secara terpisah
d) Dark mode tidak didukung oleh Tailwind

Pertanyaan 4: Class apa yang digunakan untuk membuat flex container dengan item rata tengah secara horizontal dan vertikal?

a) flex-center
b) flex justify-center items-center
c) flex middle center
d) align-center justify-center

Pertanyaan 5: Di file mana Anda menambahkan custom colors di Tailwind CSS?

a) styles.css
b) tailwind.config.js
c) index.html
d) package.json