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>
AspekCSS tradisionalUtility-first
Menamai classHarus memikirkan nama (.notif-wrapper-inner)Tidak perlu
Ukuran CSSTumbuh terus seiring fiturRelatif stabil (utility dipakai ulang)
Mengubah tampilanBuka file CSS, cari selectorUbah class di markup
Efek sampingMengubah .card bisa merusak halaman lainPerubahan lokal pada elemen itu
KonsistensiBergantung disiplinDipaksa 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": {} },
};
MetodePaketKapan
Vite plugintailwindcss, @tailwindcss/viteProyek berbasis Vite
CLItailwindcss, @tailwindcss/cliTanpa bundler / SSG
PostCSStailwindcss, @tailwindcss/postcssNext.js, setup PostCSS lain

3. Membaca Nama Utility

Pola umumnya {properti}-{nilai}:

ClassCSSCatatan
p-4padding: calc(var(--spacing) * 4)1 unit = 0.25rem → 1rem
px-6, mt-2padding horizontal, margin-topx, y, t, r, b, l
text-sm, text-gray-700ukuran font, warna teksPrefix sama, arti dari nilai
bg-blue-600/80background dengan opacity 80%Slash untuk opacity
flex gap-4 items-centerflexbox
grid grid-cols-3grid 3 kolom
w-full, max-w-proselebar
rounded-lg, shadow-mdradius, bayangan
w-[37px], bg-[#b45309]nilai arbitraryHindari 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.

PrefixMin-widthKira-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>
VariantKapan 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

  1. Masih menulis @tailwind base/components/utilities. Itu sintaks v3; di v4 cukup @import "tailwindcss";.
  2. Membuat tailwind.config.js karena kebiasaan. Di v4 konfigurasi ada di CSS (@theme). Config JS hanya untuk kompatibilitas lewat @config.
  3. Desktop-first. Menulis hidden sm:block lalu bingung kenapa hilang di HP. Ingat: tanpa prefix = semua ukuran, prefix = “mulai dari”.
  4. Membangun nama class secara dinamis (`bg-${warna}-500`). Tailwind memindai teks; class yang tidak tertulis utuh tidak ikut di-generate.
  5. Terlalu banyak nilai arbitrary (mt-[13px]). Ini melewati design system; tambahkan token di @theme jika nilai itu dipakai berulang.
  6. Lupa focus-visible: pada elemen interaktif, sehingga navigasi keyboard tidak terlihat.
  7. Kebingungan dengan paket lama. Di v4, CLI terpisah di @tailwindcss/cli dan 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 @theme dan @custom-variant.

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

Comments