Tailwind CSS adalah framework CSS yang seluruh gayanya diekspresikan sebagai kelas utilitas kecil, dan kerangka proyek Laravel menyertakannya sebagai gaya bawaan. Topik ini membahas bentuk kelas utilitas, alasan kerangka Laravel mengadopsinya, serta cara engine Tailwind menghasilkan CSS final dari pemindaian berkas sumber. Setelah membacanya, keputusan menggunakan atau tidak menggunakan Tailwind pada aplikasi sendiri dapat diambil dengan alasan teknis yang jelas.
Bentuk kelas utilitas#
Pendekatan utility-first berarti setiap deklarasi CSS dibungkus menjadi satu kelas dengan satu fungsi. Kelas flex berisi display: flex, kelas p-6 berisi padding: 1.5rem, dan kelas max-w-2xl berisi batas lebar 42 rem. Gaya dirangkai langsung pada atribut class elemennya, seperti main pada layout aplikasi catatan yang menggunakan class="mx-auto max-w-2xl p-6", yaitu konten dipusatkan, lebarnya dibatasi, dan diberi jarak dalam. Nama kelas semantik seperti konten-utama tidak diperlukan, sehingga tidak ada upaya mencari nama untuk gaya yang bentuknya belum jelas.
Perbandingan berikut menampilkan kartu yang sama dengan dua pendekatan. Tampilannya identik, tetapi kartu pertama menyimpan gaya pada nama kelas yang didefinisikan sendiri, sedangkan kartu kedua menyusunnya dari kelas utilitas. Jalankan demo berikut, lalu perhatikan bahwa perbedaannya ada pada tempat gaya disimpan, bukan pada hasil visualnya.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kartu yang sama, dua pendekatan</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<div class="kolom-demo">
<section>
<h2>CSS semantik</h2>
<article class="kartu">
<h3>Catatan belajar Laravel</h3>
<p>Ringkasan materi routing dan controller minggu ini.</p>
<button type="button">Buka catatan</button>
</article>
</section>
<section>
<h2>Kelas utilitas</h2>
<article class="mx-auto max-w-xs rounded-lg border border-gray-200 bg-white p-6 shadow-sm">
<h3 class="text-lg font-semibold">Catatan belajar Laravel</h3>
<p class="mt-2 text-sm text-gray-500">Ringkasan materi routing dan controller minggu ini.</p>
<button type="button" class="mt-4 rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-700">Buka catatan</button>
</article>
</section>
</div>
<style>
/* Bagian 1: gaya dasar demo */
body {
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
background: #f1f5f9;
color: #0f172a;
}
.kolom-demo {
display: flex;
gap: 40px;
flex-wrap: wrap;
}
h2 {
font-size: 13px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #64748b;
}
/* Bagian 2: CSS semantik, nama kelas dikarang sendiri */
.kartu {
max-width: 20rem;
background: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
padding: 1.5rem;
box-shadow: 0 1px 2px rgb(0 0 0 / 0.05);
}
.kartu h3 {
margin: 0;
font-size: 1.125rem;
font-weight: 600;
}
.kartu p {
margin: 0.5rem 0 0;
font-size: 0.875rem;
color: #6b7280;
}
.kartu button {
margin-top: 1rem;
border: 0;
cursor: pointer;
border-radius: 0.375rem;
background: #2563eb;
color: #ffffff;
padding: 0.5rem 1rem;
font-size: 0.875rem;
font-weight: 600;
}
.kartu button:hover {
background: #1d4ed8;
}
/* Bagian 3: definisi kelas utilitas, satu kelas satu aturan,
bentuknya sama dengan yang dihasilkan engine Tailwind */
.mx-auto { margin-inline: auto; }
.max-w-xs { max-width: 20rem; }
.rounded-lg { border-radius: 0.5rem; }
.rounded-md { border-radius: 0.375rem; }
.border { border-style: solid; border-width: 1px; }
.border-gray-200 { border-color: #e5e7eb; }
.bg-white { background-color: #ffffff; }
.bg-blue-600 { background-color: #2563eb; }
.hover\:bg-blue-700:hover { background-color: #1d4ed8; }
.p-6 { padding: 1.5rem; }
.px-4 { padding-inline: 1rem; }
.py-2 { padding-block: 0.5rem; }
.mt-2 { margin-top: 0.5rem; }
.mt-4 { margin-top: 1rem; }
.text-lg { font-size: 1.125rem; line-height: 1.75rem; }
.text-sm { font-size: 0.875rem; line-height: 1.25rem; }
.font-semibold { font-weight: 600; }
.text-gray-500 { color: #6b7280; }
.text-white { color: #ffffff; }
.shadow-sm { box-shadow: 0 1px 2px rgb(0 0 0 / 0.05); }
section article {
margin-top: 8px;
}
/* Gaya dasar demo meniru preflight Tailwind: margin bawaan
elemen dihapus, sehingga jarak antarelemen berasal dari kelas */
section h3, section p {
margin: 0;
}
</style></body>
</html>Berkas index.css pada demo mendefinisikan setiap kelas utilitas secara terpisah, satu kelas satu aturan, persis seperti bentuk keluaran engine Tailwind. Gaya dasar demo yang menghapus margin bawaan elemen meniru preflight, yaitu lapisan reset bawaan Tailwind, sehingga jarak antarelemen pada kartu kedua jelas berasal dari kelas mt-2 dan mt-4, bukan dari margin bawaan browser.
Alasan kerangka Laravel mengadopsinya#
Keputusan menjadikan Tailwind gaya bawaan didasarkan pada beberapa keunggulan praktis berikut.
- Gaya tersimpan bersama markahnya. Perubahan tampilan dilakukan pada berkas template yang sama, sehingga tidak ada perpindahan bolak-balik antara HTML dan berkas CSS.
- Tidak ada penamaan kelas yang dipaksakan. Kelas utilitas memiliki arti tetap, sehingga dua pengembang yang menulis komponen serupa menghasilkan kelas yang sama.
- Skala desain tetap konsisten. Nilai jarak dan ukuran huruf mengikuti tangga yang sudah ditetapkan, misalnya
p-4,p-6, danp-8, sehingga tampilan tidak menumpuk nilai piksel karangan. - CSS final tetap kecil. Engine Tailwind hanya menghasilkan aturan untuk kelas yang benar-benar digunakan, mekanisme yang dibahas pada bagian berikutnya.
Konsistensi itu berlaku pada seluruh bagian bawaan Laravel. Starter kit resmi menggunakan Tailwind pada seluruh komponennya, dan halaman sambutan proyek baru bahkan membawa salinan CSS Tailwind yang sudah terkompilasi agar tetap bergaya sebelum langkah build pertama dijalankan.
Berkas app.css bawaan#
Kerangka proyek memuat gaya Tailwind melalui satu entry point, yaitu resources/css/app.css, dan isinya persis seperti berikut.
@import 'tailwindcss';
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
@source '../../storage/framework/views/*.php';
@theme {
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol', 'Noto Color Emoji';
}Directive @import 'tailwindcss' memuat seluruh lapisan framework, sedangkan dua directive @source menambahkan lokasi pemindaian di luar proyek, yaitu template paginasi milik framework dan template hasil kompilasi Blade pada storage/framework/views. Kedua lokasi itu perlu didaftarkan karena template paginasi bawaan menggunakan kelas utilitas di dalam berkas milik framework, dan template yang sudah dikompilasi juga ikut dipindai. Blok @theme menetapkan token desain, di sini keluarga huruf sans-serif bawaan aplikasi. Konfigurasi versi 4 memang berbasis CSS seperti ini, sehingga berkas tailwind.config.js tidak lagi dibuat secara default, sedangkan directive @config tetap tersedia apabila berkas konfigurasi JavaScript lama masih diperlukan.
Alur dari berkas sumber hingga CSS final dirangkum pada diagram berikut.
.gitignore, ditambah lokasi dari directive @source. Kelas yang tidak pernah muncul pada berkas sumber tidak akan muncul pada CSS final.
Kelas utilitas pada template sambutan#
Template sambutan bawaan resources/views/welcome.blade.php menggunakan kelas utilitas di setiap bagiannya. Isi beberapa atribut class pertama pada berkas itu dapat diperiksa langsung.
# memeriksa kelas utilitas pada template sambutan bawaan
cd ~/aplikasi-catatan
grep -o 'class="[^"]*"' resources/views/welcome.blade.php | head -n 4
grep -o 'class="[^"]*"' resources/views/welcome.blade.php | wc -lclass="bg-[#FDFDFC] dark:bg-[#0a0a0a] text-[#1b1b18] flex p-6 lg:p-8 items-center lg:justify-center min-h-screen flex-col"
class="w-full lg:max-w-4xl max-w-[335px] text-sm mb-6 not-has-[nav]:hidden"
class="flex items-center justify-end gap-4"
class="inline-block px-5 py-1.5 dark:text-[#EDEDEC] border-[#19140035] hover:border-[#1915014a] border text-[#1b1b18] dark:border-[#3E3E3A] dark:hover:border-[#62605b] rounded-sm text-sm leading-normal"
39Baris terakhir keluaran adalah jumlah seluruh atribut class pada berkas tersebut, yaitu 39. Kelas seperti p-6 dan rounded-sm adalah utilitas biasa, sedangkan bg-[#FDFDFC] menunjukkan arbitrary value, yaitu nilai yang ditulis langsung di dalam tanda kurung siku. Awalan seperti dark:, lg:, hover:, dan starting: disebut variant, yaitu kondisi yang membuat aturan kelas hanya berlaku pada keadaan tertentu, misalnya layar gelap, layar lebar, kursor di atas elemen, atau kondisi awal animasi masuk.
Susunan kelas pada baris pertama juga memperlihatkan cara pendekatan ini merakit layout tanpa satu baris CSS pun yang ditulis sendiri. Kelas min-h-screen membuat halaman memenuhi tinggi layar, flex items-center memusatkan isinya secara vertikal, dan lg:justify-center memusatkannya secara horizontal pada layar lebar. Salinan CSS terkompilasi yang tertanam pada template sambutan hanya bertahan sampai build pertama, karena setelah public/build tersedia, kelas yang sama dimuat dari berkas hasil resources/css/app.css.
Batas praktis dan ekstraksi komponen#
Kelas utilitas tidak menghapus kebutuhan abstraksi. String kelas yang panjang sering berulang pada banyak elemen, dan menyalinnya secara manual membuat perubahan satu warna tombol harus dilakukan di belasan tempat. Solusi Laravel untuk pengulangan semacam ini adalah komponen Blade, tempat kelas utilitas ditulis sekali. Abstraksi ini sebaiknya baru dilakukan setelah pengulangan yang nyata muncul, karena komponen yang dibuat terlalu dini untuk satu kali penggunaan justru menambah lapisan tanpa manfaat.
<button {{ $attributes->merge(['class' => 'rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white']) }}>
{{ $slot }}
</button>Setelah disimpan sebagai resources/views/components/tombol.blade.php, pemanggilan <x-tombol>Simpan catatan</x-tombol> menghasilkan tombol yang bergaya sama di seluruh aplikasi. Metode $attributes->merge() menjaga fleksibilitasnya, karena kelas tambahan dari pemanggil digabungkan dengan kelas bawaan komponen, bukan menimpanya. Pemanggilan <x-tombol class="w-full"> tetap mempertahankan warna dan radius, dengan lebar penuh sebagai tambahan. Tailwind mengurus gaya, Blade mengurus pengulangan, dan keduanya saling melengkapi.
Kesalahan umum#
Kesalahan pertama adalah salah ketik pada kelas utilitas, misalnya menulis text-ceter alih-alih text-center. Engine Tailwind tidak menampilkan error untuk kelas yang tidak dikenalnya. Kelas yang salah itu diabaikan, dan elemen tampil tanpa gaya yang dimaksud. Karena aturan hanya dihasilkan untuk kelas yang terdeteksi, pemeriksaan dilakukan dengan membaca CSS final atau menggunakan ekstensi editor yang menyarankan nama kelas resmi.
Kesalahan kedua adalah membawa kebiasaan versi 3, yaitu membuat tailwind.config.js lalu mengharapkan versi 4 membacanya. Konfigurasi versi 4 berbasis CSS pada blok @theme, sehingga penyesuaian token desain ditulis di app.css, sedangkan berkas konfigurasi JavaScript lama hanya digunakan apabila dipanggil eksplisit dengan directive @config.
Kesalahan ketiga adalah memperlakukan nilai di dalam tanda kurung siku sebagai pengganti skala desain. Kelas seperti mt-[17px] sah digunakan, tetapi tumpukan nilai arbitrer yang bervariasi mengembalikan masalah yang justru dihindari oleh pendekatan Tailwind, yaitu tangga jarak yang tidak konsisten. Nilai arbitrer cukup digunakan sesekali, sedangkan nilai yang berulang lebih baik didefinisikan pada blok @theme.
Ringkasan#
- Tailwind mengekspresikan gaya sebagai kelas utilitas kecil yang dirangkai pada atribut
class, dan kerangka Laravel menyertainya sebagai gaya bawaan beserta entry pointresources/css/app.css. - Alasan adopsinya mencakup gaya yang tersimpan bersama markah, nama kelas yang tetap, skala desain yang konsisten, dan CSS final yang hanya berisi kelas terpakai.
- Engine versi 4 memindai berkas sumber secara otomatis, ditambah lokasi dari directive
@sourcedan token desain dari blok@theme. - Kelas utilitas yang berulang sebaiknya diekstraksi menjadi komponen Blade agar perubahan gaya terpusat.
Referensi#
- Styling with utility classes — Tailwind CSS — Dokumentasi resmi konsep kelas utilitas dan cara menyusunnya.
- Detecting classes in source files — Tailwind CSS — Mekanisme pemindaian berkas sumber pada versi 4.
- Functions and directives — Tailwind CSS
— Daftar directive seperti
@import,@source,@theme, dan@config. - Theme — Tailwind CSS
— Kustomisasi token desain melalui blok
@theme. - Frontend — Laravel — Gambaran umum tumpukan frontend bawaan Laravel.