September 28, 2026
Dasar Tailwind CSS v4.
Memahami pendekatan utility-first, instalasi Tailwind CSS v4 dengan @import "tailwindcss" lewat plugin Vite atau CLI, serta cara kerja responsive variants dan state variants seperti hover, focus, dan group.
Tailwind CSS adalah framework CSS utility-first: alih-alih menulis class semantik seperti .card lalu mendefinisikan CSS-nya, kita menyusun tampilan langsung di HTML dari class kecil yang masing-masing melakukan satu hal (p-4, rounded-lg, bg-white). Catatan ini memakai Tailwind v4, yang konfigurasinya pindah dari tailwind.config.js ke dalam file CSS.
Jika properti CSS dasarnya masih asing, baca dulu Pengantar Dasar-Dasar CSS — Tailwind hanyalah cara lain menulis CSS yang sama.
1. Utility-first: CSS Tradisional vs Tailwind
CSS tradisional:
<div class="notif">
<p class="notif-judul">Pesanan dikirim</p>
</div>
<style>
.notif { display: flex; padding: 1rem; border-radius: .5rem; background: #fff; box-shadow: 0 1px 3px rgb(0 0 0 / .1); }
.notif-judul { font-weight: 600; color: #111827; }
</style>
Tailwind:
<div class="flex rounded-lg bg-white p-4 shadow-sm">
<p class="font-semibold text-gray-900">Pesanan dikirim</p>
</div>
| Aspek | CSS tradisional | Utility-first |
|---|---|---|
| Menamai class | Harus memikirkan nama (.notif-wrapper-inner) | Tidak perlu |
| Ukuran CSS | Tumbuh terus seiring fitur | Relatif stabil (utility dipakai ulang) |
| Mengubah tampilan | Buka file CSS, cari selector | Ubah class di markup |
| Efek samping | Mengubah .card bisa merusak halaman lain | Perubahan lokal pada elemen itu |
| Konsistensi | Bergantung disiplin | Dipaksa oleh design token (skala spacing, warna) |
Kekhawatiran “HTML jadi panjang” nyata, tapi diatasi dengan komponen (partial template, komponen React/Blade) — dibahas di catatan Pola & Praktik Tailwind .
2. Instalasi Tailwind v4
Perubahan besar di v4: tidak ada lagi @tailwind base; @tailwind components; @tailwind utilities;, dan file config JavaScript tidak wajib. Cukup satu baris:
/* src/style.css */
@import "tailwindcss";
Tailwind v4 juga mendeteksi file sumber otomatis — tidak perlu array content seperti di v3.
Opsi A: Plugin Vite (disarankan untuk proyek Vite, React, Vue, Laravel)
npm create vite@latest my-project
cd my-project
npm install tailwindcss @tailwindcss/vite
// vite.config.ts
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
plugins: [tailwindcss()],
});
Import style.css dari entry point (main.ts/main.tsx), lalu npm run dev.
Opsi B: Tailwind CLI (tanpa bundler)
Cocok untuk static site generator seperti Hugo — situs ini sendiri memakai cara ini.
npm install tailwindcss @tailwindcss/cli
npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --watch
<link href="/dist/output.css" rel="stylesheet" />
Build produksi tinggal menambahkan --minify.
Opsi C: PostCSS
Untuk framework yang sudah memakai PostCSS: pasang @tailwindcss/postcss lalu daftarkan di postcss.config.mjs:
export default {
plugins: { "@tailwindcss/postcss": {} },
};
| Metode | Paket | Kapan |
|---|---|---|
| Vite plugin | tailwindcss, @tailwindcss/vite | Proyek berbasis Vite |
| CLI | tailwindcss, @tailwindcss/cli | Tanpa bundler / SSG |
| PostCSS | tailwindcss, @tailwindcss/postcss | Next.js, setup PostCSS lain |
3. Membaca Nama Utility
Pola umumnya {properti}-{nilai}:
| Class | CSS | Catatan |
|---|---|---|
p-4 | padding: calc(var(--spacing) * 4) | 1 unit = 0.25rem → 1rem |
px-6, mt-2 | padding horizontal, margin-top | x, y, t, r, b, l |
text-sm, text-gray-700 | ukuran font, warna teks | Prefix sama, arti dari nilai |
bg-blue-600/80 | background dengan opacity 80% | Slash untuk opacity |
flex gap-4 items-center | flexbox | |
grid grid-cols-3 | grid 3 kolom | |
w-full, max-w-prose | lebar | |
rounded-lg, shadow-md | radius, bayangan | |
w-[37px], bg-[#b45309] | nilai arbitrary | Hindari bila bisa pakai token |
Karena spacing di v4 dihitung dari satu variabel --spacing, nilai seperti p-13 atau mt-17 juga valid tanpa konfigurasi tambahan.
4. Responsive Variants
Tailwind mobile-first: class tanpa prefix berlaku di semua ukuran, prefix breakpoint berlaku mulai lebar tersebut ke atas.
| Prefix | Min-width | Kira-kira |
|---|---|---|
sm: | 40rem (640px) | Ponsel landscape |
md: | 48rem (768px) | Tablet |
lg: | 64rem (1024px) | Laptop |
xl: | 80rem (1280px) | Desktop |
2xl: | 96rem (1536px) | Layar lebar |
<!-- 1 kolom di HP, 2 di tablet, 4 di laptop -->
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
<div class="rounded-lg bg-white p-4">Item</div>
<!-- ... -->
</div>
<!-- Sembunyikan di desktop -->
<button class="lg:hidden">Menu</button>
Untuk membatasi hanya di rentang tertentu, gabungkan dengan max-*: md:max-lg:flex berarti “hanya antara md dan lg”.
Tailwind v4 juga punya container queries bawaan — responsif terhadap lebar parent, bukan viewport:
<div class="@container">
<div class="flex flex-col @md:flex-row">...</div>
</div>
5. State Variants
<button
class="rounded-md bg-amber-700 px-4 py-2 text-white
hover:bg-amber-800 focus-visible:outline-2 focus-visible:outline-offset-2
active:scale-95 disabled:opacity-50"
>
Simpan
</button>
| Variant | Kapan aktif |
|---|---|
hover: | Kursor di atas elemen (v4: hanya di perangkat yang mendukung hover) |
focus: / focus-visible: | Fokus / fokus via keyboard |
active: | Sedang ditekan |
disabled: | Elemen form disabled |
first:, last:, odd: | Posisi anak |
dark: | Mode gelap |
group-hover: | Parent bertanda group di-hover |
peer-checked: | Sibling bertanda peer dicentang |
aria-expanded:, data-[state=open]: | Atribut ARIA / data |
group dan peer
<a href="#" class="group block rounded-lg p-4 hover:bg-gray-50">
<h3 class="font-semibold group-hover:text-amber-700">Judul artikel</h3>
<p class="text-sm text-gray-500">Ringkasan...</p>
</a>
<label>
<input type="checkbox" class="peer sr-only" />
<span class="rounded border px-3 py-1 peer-checked:bg-amber-700 peer-checked:text-white">
Pilih
</span>
</label>
Variant bisa ditumpuk: dark:md:hover:bg-gray-800 aktif saat mode gelap, layar ≥ md, dan di-hover.
Kesalahan Umum
- Masih menulis
@tailwind base/components/utilities. Itu sintaks v3; di v4 cukup@import "tailwindcss";. - Membuat
tailwind.config.jskarena kebiasaan. Di v4 konfigurasi ada di CSS (@theme). Config JS hanya untuk kompatibilitas lewat@config. - Desktop-first. Menulis
hidden sm:blocklalu bingung kenapa hilang di HP. Ingat: tanpa prefix = semua ukuran, prefix = “mulai dari”. - Membangun nama class secara dinamis (
`bg-${warna}-500`). Tailwind memindai teks; class yang tidak tertulis utuh tidak ikut di-generate. - Terlalu banyak nilai arbitrary (
mt-[13px]). Ini melewati design system; tambahkan token di@themejika nilai itu dipakai berulang. - Lupa
focus-visible:pada elemen interaktif, sehingga navigasi keyboard tidak terlihat. - Kebingungan dengan paket lama. Di v4, CLI terpisah di
@tailwindcss/clidan PostCSS di@tailwindcss/postcss.
Ringkasan
- Utility-first: susun tampilan dari class kecil, abstraksi lewat komponen.
- v4:
@import "tailwindcss"+ plugin Vite / CLI / PostCSS, deteksi file otomatis. - Mobile-first: prefix breakpoint berarti “mulai dari ukuran ini”.
- State variants (
hover,focus-visible,group-*,peer-*) bisa ditumpuk. - Lanjut ke Kustomisasi Tailwind v4
untuk
@themedan@custom-variant.

Hey! I’m Fanny, the software engineer tending to this digital garden. You can read more about me, or subscribe by email.