Kenapa ini penting
Di modul sebelumnya kamu menulis CSS di file terpisah: memikirkan nama class (.card-header-title-big?), bolak-balik antara file .jsx dan .css, lalu khawatir CSS lama tidak terpakai tapi takut dihapus. Pendekatan utility-first membalik cara kerja itu. Kamu menyusun tampilan langsung di JSX dengan class kecil yang masing-masing punya satu tugas: p-4 (padding), text-lg (ukuran teks), bg-blue-600 (warna latar), rounded-lg (sudut membulat).
Framework utility-first paling populer adalah Tailwind CSS. Banyak proyek React modern, termasuk template komponen populer, memakai Tailwind sebagai default. Di modul ini kamu cukup bisa memasangnya di proyek React + Vite dan memahami cara berpikirnya. Pembahasan lengkap class, kustomisasi tema, dan responsive design ada di materi 3.2.
Konsep inti
Apa itu utility class?
Utility class adalah class CSS yang sangat kecil dan spesifik. Contoh px-4 artinya padding kiri-kanan 1rem, font-bold artinya font-weight: 700. Alih-alih menulis:
.tombol { padding: 0.5rem 1rem; background: #2563eb; color: white; border-radius: 0.5rem; }
kamu menulis langsung di elemen: className="px-4 py-2 bg-blue-600 text-white rounded-lg".
Analogi: CSS biasa itu seperti memesan baju jahit (kamu desain dari nol, beri nama, simpan polanya). Utility class itu seperti LEGO: potongan kecil yang sudah standar, tinggal disusun. Hasilnya konsisten karena semua orang memakai potongan yang sama (skala spacing dan warna yang sama).
Kenapa cocok dengan React?
Keberatan umum terhadap utility class adalah "className jadi panjang dan berulang". Di React masalah itu hilang dengan sendirinya: kalau tombol dipakai di 30 tempat, kamu tidak menyalin class-nya 30 kali, tapi membuat komponen <Button> sekali. Komponen adalah unit reuse-nya, bukan class CSS. Ini sebabnya React dan Tailwind sering dipasangkan.
Tailwind v4: konfigurasi CSS-first
Tailwind v4 (versi saat ini 4.3.3, dicek dengan npm view tailwindcss version) berbeda cukup jauh dari v3 yang mungkin kamu temukan di tutorial lama:
| Hal | Tailwind v3 (lama) | Tailwind v4 (sekarang) |
|---|---|---|
| Integrasi Vite | PostCSS + autoprefixer | Plugin resmi @tailwindcss/vite |
| File konfigurasi | tailwind.config.js |
Tidak wajib; konfigurasi di CSS lewat @theme |
| Import di CSS | @tailwind base; @tailwind components; @tailwind utilities; |
Satu baris @import "tailwindcss"; |
| Deteksi file | Isi manual array content |
Otomatis memindai file proyek |
Jadi kalau kamu menemukan tutorial yang menyuruh npx tailwindcss init -p, itu cara v3. Abaikan untuk proyek baru.
Alur kerja sehari-hari
- Tulis struktur JSX dulu.
- Tambahkan utility class sedikit demi sedikit sambil melihat browser (Vite me-reload otomatis).
- Kalau satu pola dipakai berulang, ekstrak menjadi komponen React, bukan menjadi class CSS baru.
- Untuk nilai dinamis (misalnya lebar dari data), tetap boleh memakai style object dari modul sebelumnya.
Satu aturan penting: Tailwind memindai teks di file kamu untuk mencari nama class. Jadi nama class harus ditulis utuh. 'bg-' + warna + '-600' tidak akan terdeteksi, sehingga CSS-nya tidak dibuat. Pakai peta object berisi nama class lengkap.
Membaca utility class seperti kalimat
Nama class Tailwind punya pola yang konsisten, jadi kamu tidak perlu menghafal semuanya. Bagian awal menunjukkan property, bagian akhir menunjukkan nilai dari skala yang sudah disediakan. p-4 artinya padding dengan skala 4 (1rem), mt-2 artinya margin-top skala 2, text-gray-900 artinya warna teks abu-abu paling gelap, w-full artinya lebar 100%. Awalan sebelum titik dua adalah kondisi: hover:bg-blue-700 hanya berlaku saat kursor di atas elemen, disabled:opacity-50 hanya saat tombol disabled, md:flex hanya pada layar ukuran sedang ke atas.
Dengan pola itu, className="mt-4 w-full rounded-lg bg-brand px-4 py-2 text-white disabled:opacity-50" bisa dibaca seperti kalimat: beri jarak atas, lebar penuh, sudut membulat, latar warna brand, padding horizontal dan vertikal, teks putih, dan pudar saat nonaktif.
Ekstensi editor Tailwind CSS IntelliSense untuk VS Code sangat membantu pemula: ia menampilkan saran class saat mengetik dan memperlihatkan CSS asli ketika kursor diarahkan ke sebuah class. Ini cara tercepat belajar "class ini sebenarnya CSS apa".
Satu hal lagi: Tailwind hanya membuat CSS untuk class yang benar-benar kamu pakai. Jadi walaupun ada ribuan kemungkinan class, file CSS hasil build tetap kecil.
Contoh kode
Langkah setup di proyek React + Vite baru:
# 1. Buat proyek React (template JavaScript)
npm create vite@latest toko-saya -- --template react
cd toko-saya
npm install
# 2. Pasang Tailwind v4 dan plugin Vite-nya
npm install tailwindcss @tailwindcss/vite
# 3. Cek versi yang terpasang
npm ls tailwindcss
# → tailwindcss@4.3.3 (atau lebih baru)
// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
// plugin react untuk JSX & Fast Refresh, plugin tailwindcss untuk utility class
plugins: [react(), tailwindcss()],
});
/* src/index.css, hapus isi bawaan template, ganti dengan ini */
@import "tailwindcss";
/* opsional: token tema sendiri, gaya CSS-first v4 */
@theme {
--color-brand: #7c3aed;
}
/* sekarang class bg-brand dan text-brand bisa dipakai */
Komponen kartu produk dengan utility class:
// ProductCard.jsx
const warnaStok = {
// nama class ditulis utuh supaya terdeteksi Tailwind
habis: 'bg-red-100 text-red-700',
sedikit: 'bg-yellow-100 text-yellow-800',
aman: 'bg-green-100 text-green-700',
};
export default function ProductCard({ nama, harga, stok }) {
const status = stok === 0 ? 'habis' : stok < 5 ? 'sedikit' : 'aman';
return (
<article className="max-w-xs rounded-xl border border-gray-200 p-4 shadow-sm hover:shadow-md transition">
<h3 className="text-lg font-semibold text-gray-900">{nama}</h3>
<p className="mt-1 text-brand font-bold">Rp {harga.toLocaleString('id-ID')}</p>
<span className={`mt-3 inline-block rounded-full px-3 py-1 text-xs ${warnaStok[status]}`}>
Stok: {stok}
</span>
<button
disabled={stok === 0}
className="mt-4 w-full rounded-lg bg-brand px-4 py-2 text-white disabled:opacity-50"
>
Beli
</button>
</article>
);
}
// <ProductCard nama="Kopi Gayo" harga={85000} stok={3} />
// → kartu dengan harga "Rp 85.000" dan badge kuning "Stok: 3"
Kesalahan umum
- Mengikuti tutorial Tailwind v3. Membuat
tailwind.config.jsdan menulis@tailwind basetidak diperlukan di v4. Cukup plugin@tailwindcss/vitedan@import "tailwindcss";. - Menyusun nama class secara dinamis.
`text-${warna}-500`tidak terdeteksi saat build sehingga style-nya tidak ada. Simpan nama class lengkap di object sepertiwarnaStok. - Lupa menambahkan plugin di
vite.config.js. Hasilnya class tidak berpengaruh sama sekali. Pastikantailwindcss()ada di arrayplugins. - Menyalin className panjang ke banyak tempat. Kalau pola berulang, buat komponen React. Di situlah reuse terjadi.
- Mencampur CSS bawaan template Vite. File
index.cssdanApp.cssbawaan berisi style yang bisa bertabrakan. Kosongkan dulu sebelum memakai Tailwind.
Latihan
- Mudah, Pasang Tailwind v4 di proyek Vite baru, lalu ubah
App.jsxagar menampilkan judulHalo Tailwinddengan classtext-3xl font-bold text-blue-600. - Sedang, Buat komponen
Alertdengan propstipe(info,sukses,bahaya) yang memilih warna lewat object peta class lengkap. - Menantang, Tambahkan token warna
--color-branddi@theme, lalu buat komponenButtonyang menerima propsvarian(solidatauoutline) dan memakaibg-brand/border-brand.
Lihat solusi
// 1. App.jsx (setelah setup seperti contoh di atas)
export default function App() {
return <h1 className="text-3xl font-bold text-blue-600">Halo Tailwind</h1>;
}
// 2. Alert.jsx
const gaya = {
info: 'bg-blue-50 text-blue-800 border-blue-200',
sukses: 'bg-green-50 text-green-800 border-green-200',
bahaya: 'bg-red-50 text-red-800 border-red-200',
};
export function Alert({ tipe = 'info', children }) {
return <div className={`rounded-lg border p-4 ${gaya[tipe]}`}>{children}</div>;
}
// <Alert tipe="bahaya">Password salah</Alert> → kotak merah muda
/* 3. index.css */
@import "tailwindcss";
@theme {
--color-brand: #7c3aed;
}
// 3. Button.jsx
const varianKelas = {
solid: 'bg-brand text-white hover:opacity-90',
outline: 'border-2 border-brand text-brand hover:bg-brand hover:text-white',
};
export function Button({ varian = 'solid', children, ...rest }) {
return (
<button className={`rounded-lg px-4 py-2 font-medium transition ${varianKelas[varian]}`} {...rest}>
{children}
</button>
);
}
Ringkasan
- Utility-first berarti menyusun tampilan dari class kecil bertugas tunggal langsung di JSX.
- Di React, reuse dilakukan lewat komponen, sehingga className panjang tidak perlu diulang.
- Tailwind v4 dipasang dengan
npm install tailwindcss @tailwindcss/vite, plugintailwindcss()di Vite, dan@import "tailwindcss";. - Konfigurasi tema di v4 ditulis di CSS lewat
@theme, bukantailwind.config.js. - Nama class harus ditulis utuh agar terdeteksi; detail Tailwind dibahas di materi 3.2.