D
P
0
← Semua artikel Read in English

Jebakan Build-Time Tailwind v4

Footer `lg:grid-cols-[1.6fr_repeat(6,minmax(0,1fr))]` Jatuh ke Tiga Kolom di Tailwind v4? Arbitrary Value yang Hilang Saat Compile

· · 4 menit baca
Footer `lg:grid-cols-[1.6fr_repeat(6,minmax(0,1fr))]` Jatuh ke Tiga Kolom di Tailwind v4? Arbitrary Value yang Hilang Saat Compile

Footer situs personal yang saya kerjakan memakai lg:grid-cols-6. Kolom brand mengambil satu sel, lima kolom link mengisi sisa baris pertama, dan kolom Portfolio, yang kebetulan punya lg:col-start-2, jatuh sendirian ke baris kedua tepat di bawah Products. Yang menilai itu jelek bukan klien. Saya sendiri yang merasa kolom itu terlihat canggung, berdiri sendiri di bawah.

Saya mencatat tiga jalan keluar: pindah ke lg:grid-cols-7 supaya brand dan enam kolom link muat satu baris, memisahkan blok brand dan memberi enam kolom link grid sendiri, atau menggabungkan dua kolom jadi satu. Keputusannya: footer harus satu baris.

Bentuk yang saya pilih di rilis v0.1.5 adalah arbitrary value Tailwind, supaya kolom brand lebih lebar dari enam kolom link tanpa harus keluar dari sistem utility:

<div class="grid md:grid-cols-3 lg:grid-cols-[1.6fr_repeat(6,minmax(0,1fr))]">
  <!-- brand + 6 kolom link -->
</div>

Rilis itu tercatat sudah diverifikasi hidup lewat tampilan publik yang cache-busted pada sore 24 Juni. Catatan footer berikutnya bertanggal 25 Juni, dan isinya footer di halaman publik jatuh ke md:grid-cols-3, dengan Portfolio kembali yatim di baris berikutnya.

Kenapa ini terjadi

Catatan saya dari hari itu memuat dua tuduhan, dan keduanya perlu saya tulis apa adanya sebagai dugaan, bukan kepastian.

Tuduhan pertama: Tailwind v4 membuang class arbitrary itu saat compile, dan penyebabnya koma di dalam repeat() merusak parsing arbitrary value. Yang membuat tuduhan ini terasa masuk akal adalah pembandingnya di projek yang sama. Sebagian pembanding itu baru tercatat belakangan, jadi bukan bekal yang sudah saya pegang di bulan Juni. Arbitrary grid yang memakai underscore tanpa koma, seperti md:grid-cols-[220px_1fr] dan grid-cols-[1fr_535px], terbukti bertahan di stylesheet hasil compile setelah recompile, begitu juga aspect-video. Di projek yang sama Tailwind v4 juga menolak scale-[0.8803], sehingga saya berakhir memakai inline style untuk transform itu. Jadi pola "arbitrary value tertentu tidak pernah sampai ke CSS" saya temui lebih dari sekali di codebase ini. Yang tidak pernah saya lakukan adalah mengisolasi class berkoma itu di build kosong untuk membuktikan bahwa komanya yang salah. Saya punya gejala dan pembanding, bukan bukti parser.

Tuduhan kedua menjelaskan kenapa admin melihat footer baik-baik saja sementara publik rusak: WP Rocket Remove Unused CSS. Pengunjung publik mendapat "Used CSS" yang di-inline per URL dan dibekukan sebelum class baru ada, sementara admin yang login melewati RUCSS dan page cache. Untuk bagian ini, perbaikannya prosedur cache, bukan kode.

Satu catatan versi supaya jujur: angka tailwindcss v4.3.0 di projek ini baru tercatat pada update 22 Juli, hampir sebulan setelah kejadian footer. Saya tidak punya catatan versi persis di hari itu.

Perbaikannya

Saya berhenti berdebat dengan arbitrary value dan menulis grid-nya sebagai class CSS biasa di input.css, responsif dua, tiga, lalu tujuh kolom, dengan tujuh kolom 1.6fr repeat(6, minmax(0, 1fr)) pada breakpoint lg:

.site-footer-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
 
@media (min-width: 768px) {
  .site-footer-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
 
@media (min-width: 1024px) {
  .site-footer-grid {
    grid-template-columns: 1.6fr repeat(6, minmax(0, 1fr));
  }
}

footer.php memakai class="site-footer-grid". Class ini tidak lewat parser arbitrary value sama sekali, jadi apa pun yang sebenarnya terjadi pada koma di repeat(), dia tidak lagi relevan.

Untuk sisi cache, saya menjalankan Clear Used CSS, Clear and Preload, purge Cloudflare, lalu menambahkan .site-footer-grid ke safelist RUCSS supaya rule-nya tidak dibuang lagi di regenerasi berikutnya.

Verifikasinya saya lakukan tanpa kredensial, supaya yang saya lihat benar-benar tampilan publik: footer terhitung display: grid dengan tujuh kolom. Pada lebar 1069px tiap kolom sekitar 88px, sempit tapi berfungsi, dan itu konsekuensi dari keputusan satu baris yang saya ambil sendiri. Perbaikan ini masuk commit v0.2.0 pada 25 Juni bersama footer.php, input.css, dan tailwind-compiled.css.

Kejadian kedua, sehari kemudian

Pada 26 Juni, di tema publikasi fintech yang juga dikompilasi lewat Tailwind v4 CLI ke assets/css/tailwind-compiled.css, kartu orang di halaman direktori memakai aspect-[1/1] dan aspect-[4/5]. Kedua class itu tidak menghasilkan satu rule pun di CSS hasil compile. Bug-nya laten: kartu lama sudah memakai class itu sejak awal, dan yang membuatnya menggigit adalah adanya anggota sungguhan untuk dirender. Grid "nama terbaru" saya ubah jadi data-driven lewat get_posts pada post type directory_person, dua belas terbaru, yang merender anggota sungguhan kalau ada dan placeholder peluncuran kalau tidak.

Perbaikannya sama arahnya dengan footer. Gambar kartu orang memakai inline style, bukan utility:

<img ... style="aspect-ratio: 1 / 1;">

Setelah itu tailwind-compiled.css saya kompilasi ulang dan class utility baru lainnya saya cek satu per satu, di antaranya md:grid-cols-5, sm:flex-row, lg:justify-end, dan scroll-mt-16, semuanya ada. Halaman-halamannya tayang dan ter-commit di hari yang sama. Yang membuat kasus ini menarik: pada porting awal tema itu, Tailwind dikompilasi dengan lebih dari 46 class arbitrary yang bertahan. Arbitrary value sebagai fitur jelas bekerja di sini. Yang gagal adalah bentuk tertentu.

Pelajaran

Pola yang sama muncul di tempat lain di projek yang sama, pada scrim navbar: inline style atau class CSS biasa dipilih dengan sengaja, karena arbitrary utility baru tidak akan dikompilasi, dan rule yang bergantung pada class toggle JS justru yang dibuang RUCSS. Dengan begitu Used CSS tidak perlu diwipe dan tidak ada regenerasi situs penuh yang terbuang.

Aturannya sederhana. Kalau sebuah nilai hanya dipakai di satu elemen dan bentuknya rumit, entah repeat() berkoma, rasio dengan garis miring, atau angka desimal empat digit, saya tidak lagi menaruhnya di dalam kurung siku Tailwind. Saya tulis sebagai CSS biasa, lalu buktikan keberadaannya di stylesheet hasil compile sebelum upload. Utility yang tidak cocok dengan rule mana pun tidak pernah melempar error. Dia cuma diam, dan footer kamu jatuh ke tiga kolom tanpa memberi tahu siapa pun.