Saya sedang membangun ulang homepage sebuah situs klien di tema WordPress custom. Hero-nya full-screen, min-height: 100vh, dengan video di latar yang bergerak pelan di balik headline. Di localhost semuanya rapi. Lalu saya klon situsnya ke staging pakai plugin WP Staging, buka URL-nya, dan ada garis di sana. Garis 1px, lurus sempurna, melintang dari tepi kiri ke tepi kanan viewport, kira-kira 70 persen ke bawah. Warnanya samar, semburat emas kecokelatan. Dan yang bikin merinding: garis itu memotong tepat menembus subjek di video hero. Tidak ada video natural yang punya horizon selurus dan sesejajar itu.
Yang lebih membingungkan: garis itu cuma muncul di staging. Di localhost, bersih. Saya buka dengan admin bar login, saya buka tanpa admin bar, hasilnya sama saja: lokal tanpa garis, staging dengan garis. Kode-nya identik, database-nya kloningan. Satu render bersih, satu lagi punya garis hantu di tempat yang persis sama setiap kali reload.
Deretan jalan buntu
Karena warnanya emas kecokelatan dan setipis 1px, tebakan pertama saya jelas: ini border. Saya buru border-top di bar tipis dalam hero, saya matikan satu per satu. Garisnya tetap. Saya curigai push layout dari WP admin bar, karena tinggi bar itu bisa menggeser konten. Saya nonaktifkan admin bar, garisnya tetap. Saya kejar .hp-hero::before, sebuah overlay vignette gelap di atas video, kalau-kalau ada tepi keras di gradiennya. Bukan itu.
Lalu saya pindah curiga ke video-nya sendiri. Ada mask-image di elemen video untuk fade di bagian bawah, jadi saya kira mungkin tepi mask-nya render sebagai garis di staging. Saya lepas mask-nya, garisnya tetap. Video juga punya transform: scale(1.18) untuk crop supaya framing-nya pas, jadi saya curigai tepi hasil crop. Saya nolkan transform-nya, garisnya tetap. Saya bahkan sempat mengejar kompensasi tinggi body.admin-bar yang biasa dipakai WordPress. Semua nihil.
Menyingkirkan cache dan CDN dulu
Karena bug ini cuma di staging, kecurigaan wajar berikutnya adalah CSS yang dimutasi di jalan: minifier, cache, atau CDN mengubah stylesheet sebelum sampai ke browser. Situs ini pakai LiteSpeed dan Cloudflare, jadi ada banyak lapisan yang bisa menyuntik sesuatu. Daripada menebak, saya tulis skrip debug read-only kecil untuk membandingkan apa yang benar-benar disajikan versus apa yang ada di disk:
$served = md5( wp_remote_retrieve_body( wp_remote_get( $css_url ) ) );
$disk = md5( file_get_contents( $css_path ) );
error_log( "[hero-debug] served={$served} disk={$disk}" );MD5-nya cocok. Artinya CSS yang sampai ke browser identik dengan yang di disk, jadi bukan minifier atau CDN yang menyisipkan garis. Untuk memastikan, skrip yang sama saya lebarkan: audit semua tag <style> inline di HTML tersaji, scan opsi LiteSpeed seperti css_min, css_comb, dan css_inline, lalu periksa fingerprint Cloudflare seperti cf-cache-status dan atribut Rocket Loader data-cfasync. Semua bersih. Garisnya bukan artefak build. Garisnya deterministik, lahir dari CSS yang memang saya tulis sendiri.
Akar masalahnya
Begitu cache dan CDN keluar dari daftar tersangka, saya kembali membaca stylesheet dengan mata baru, dan di sanalah pelakunya. Ada tiga aturan dekoratif yang menggambar garis jahitan putus-putus tipis di puncak beberapa section di bawah hero:
.hp-story::before,
.hp-coll::before,
.hp-stores::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: repeating-linear-gradient(
90deg,
var(--hp-mist) 0,
var(--hp-mist) 6px,
transparent 6px,
transparent 12px
);
}
/* --hp-mist: #CEC3B4; */Nilai --hp-mist adalah #CEC3B4, persis semburat emas kecokelatan yang saya lihat. Garis itu adalah tepi atas section pertama setelah hero. Di localhost, hero setinggi 100vh berakhir tepat di lipatan, jadi garis jahitan section berikutnya duduk tepat di bawah fold dan tidak pernah terlihat.
Bagian keduanya adalah biang gesernya. WP Staging menyuntik banner status oranye di setiap klon staging: sebuah blok inline <style id="wpstg-admin-bar"> dengan aturan #wpadminbar { background: #ff8d00 !important }. Banner itu menggeser seluruh konten turun sekitar 32 sampai 40px. Hero tetap 100vh di koordinat dokumen, tapi geseran itu cukup untuk membawa garis batas section, yang tadinya pas di fold, naik ke sekitar 95 persen tinggi viewport yang terlihat. Hasilnya: garis yang seharusnya tersembunyi di bawah hero jadi tampak seolah melintang di dalam hero. Localhost tidak punya banner itu, jadi garisnya tetap di bawah fold dan tak kelihatan.
Perbaikannya
Ketiga aturan ::before itu murni dekoratif, jahitan halus antar section, bukan elemen struktural yang menahan layout. Jadi perbaikannya sederhana: hapus ketiganya dari style.css.
/* Dihapus: garis jahitan dekoratif yang bocor ke dalam hero di staging.
.hp-story::before,
.hp-coll::before,
.hp-stores::before { ... }
*/Setelah dihapus, saya reload staging: hero bersih, tanpa garis, di setiap ukuran viewport. Localhost juga tetap bersih. Godaan awalnya adalah mengkompensasi geseran banner dengan menambah padding di hero, tapi itu cuma menambal gejala di satu tinggi layar dan bakal pecah di layar lain. Membuang garis dekoratif yang memang tak perlu jauh lebih bersih daripada mengejar-ngejar geseran banner.
Pelajaran
- Kalau bug visual cuma muncul di staging dan tidak di lokal, curigai apa yang disuntik lingkungan staging, bukan kode kamu. WP Staging menaruh banner oranye yang menggeser layout beberapa puluh piksel.
- Singkirkan mutasi CSS dari cache, minifier, dan CDN lebih dulu. Bandingkan MD5 CSS tersaji versus di disk sebelum menuduh stylesheet kamu sendiri.
- Garis 1px berwarna sering kali
repeating-linear-gradientatauborder, bukan bagian dari gambar atau video. Cocokkan warna garis dengan custom property di CSS kamu;#CEC3B4menunjuk langsung ke pelakunya. - Elemen dekoratif yang duduk pas di batas
100vhitu rapuh: geseran kecil apa pun bisa menariknya masuk atau keluar dari fold. Jangan sandarkan estetika pada posisi fold. - Kalau sebuah aturan cuma hiasan dan bukan penahan layout, menghapusnya lebih baik daripada menambal geseran yang memicunya.
