D
P
0

HTML & CSS

Heading Ada di DOM, Punya Dimensi, Tapi Invisible di Semua Section Gelap? Satu Rule Global `color` pada `h1-h6` Memblok Inheritance

21 Juli 2026·4 menit baca
Heading Ada di DOM, Punya Dimensi, Tapi Invisible di Semua Section Gelap? Satu Rule Global `color` pada `h1-h6` Memblok Inheritance

Sebuah situs klien yang saya kerjakan punya satu heading di halaman about yang bikin saya garuk kepala. Kliennya yang menemukan duluan: di section gelap paling atas, judul utamanya harusnya nangkring besar di tengah, tapi yang terlihat cuma latar gelap kosong. Headingnya tidak hilang. Dia ada di DOM, punya dimensi nyata (223 kali 81 piksel), teksnya utuh. Tapi mata tidak menangkap apa-apa.

Gejalanya

Refleks pertama saya menuduh yang biasa: mungkin opacity: 0, mungkin teksnya ketiban elemen lain, atau visibility: hidden. Saya inspect elemennya di DevTools dan mencoret satu per satu. Opacity 1. Visibility visible. Tidak ada overlay yang menutup. Lalu saya buka panel Computed dan nemu tersangkanya di baris paling atas: color: rgb(58, 58, 58). Abu-abu gelap. Dan latar section itu? Nyaris hitam. Dark-on-dark. Teksnya ada di sana, cuma warnanya menyatu sempurna dengan background sampai tak berbekas.

Karena yang salah warnanya, sempat saya kira ini cuma satu heading yang kelupas di satu tempat. Tapi begitu saya scroll dan cek section gelap lain, polanya berulang persis: section differentiator, story, newsletter, contact, sampai cart drawer dan halaman account. Setiap heading di section bertema gelap membawa warna abu-abu yang sama. Bug yang identik, laten di 10 lebih tempat. Yang menyelamatkan situs sejauh ini cuma kebetulan: kebanyakan heading gelap itu pendek atau ketutup gambar, jadi belum ada yang protes. Yang di about ini besar dan berdiri sendiri di tengah, jadi akhirnya ketahuan.

Akar masalahnya: warna eksplisit memutus inheritance

Di sinilah ceritanya jadi menarik. Section gelap di theme ini tidak menulis warna teks satu per satu. Mereka membalik seluruh skema lewat satu aturan di container:

.section-dark {
  background: var(--color-foreground); /* gelap */
  color: var(--color-background);      /* terang */
}

Triknya rapi: set color sekali di container, dan semua teks di dalamnya ikut jadi terang lewat inheritance. Paragraf, span, div, link, semua patuh. Kecuali heading.

Kenapa heading beda sendiri? Karena di critical.css, jauh di baris 89, ada satu aturan global:

h1, h2, h3, h4, h5, h6 {
  color: var(--color-fg);
}

Aturan ini nge-set warna heading secara eksplisit ke foreground default yang gelap. Dan di sinilah kuncinya: begitu sebuah properti punya nilai eksplisit di sebuah elemen, elemen itu berhenti mewarisi properti tersebut dari ancestor-nya. color heading bukan lagi diserahkan ke inheritance, dia sudah dipatok. Jadi ketika section gelap membalik color container jadi terang, paragraf ikut karena mereka memang menunggu warisan. Tapi heading sudah kadung punya color: var(--color-fg) sendiri, jadi mereka mengabaikan warna terang dari container dan tetap gelap. Hasilnya dark-on-dark.

Kenapa ini bukan perang specificity

Ini yang mau saya tegasin, karena gampang ketuker dengan bug lain yang pernah saya tulis. Ini bukan perang specificity. Tidak ada dua selector yang berebut lalu yang lebih spesifik menang. Aturan h1-h6 global itu menang telak, tidak dilawan siapa pun, dan justru kemenangannya itu masalahnya. Dia menetapkan warna eksplisit yang memutus rantai inheritance sebelum warna section sempat turun ke heading. Menaikkan specificity aturan section atau menumpuk !important malah bikin makin ruwet dan menyebar ke mana-mana. Akar masalahnya bukan siapa yang menang, tapi bahwa heading dikasih warna eksplisit sama sekali.

Perbaikannya

Perbaikannya satu baris, dan efeknya menyapu semua 10 lebih section sekaligus:

h1, h2, h3, h4, h5, h6 {
  color: inherit;
}

inherit mengembalikan heading ke perilaku default cascade: ambil color dari parent. Di section terang, parent-nya membawa foreground gelap, jadi heading tetap gelap seperti seharusnya. Di section gelap, parent-nya sudah dibalik jadi terang, jadi heading ikut terang. Satu kata, dan setiap heading di seluruh situs otomatis nyambung lagi ke skema warna section tempat dia tinggal. Saya tidak perlu menyentuh 10 lebih section satu per satu.

Setelah diganti, saya balik ke about: heading utamanya langsung muncul putih bersih di latar gelap. Saya sisir juga section terang untuk memastikan tidak ada regresi, dan semua heading di sana tetap gelap seperti sebelumnya. inherit tidak memaksakan warna apa pun; dia cuma menyerahkan keputusan ke section, dan section memang sudah tahu warnanya harus apa.

Yang saya bawa pulang

  • Heading yang seolah hilang tapi punya dimensi nyata di DOM hampir selalu masalah warna, bukan layout. Cek color di panel Computed sebelum ngejar display atau z-index.
  • Properti dengan nilai eksplisit berhenti diwarisi. Aturan global color pada h1-h6 diam-diam memutus heading dari skema warna yang dibalik section.
  • Pola membalik skema lewat color di container cuma jalan untuk elemen yang mewarisi. Elemen dengan warna eksplisit sendiri kebal terhadap flip itu.
  • color: inherit di heading mengembalikan mereka ke rantai inheritance, jadi satu perubahan memperbaiki setiap section gelap sekaligus.
  • Ini beda dari perang specificity: di sini tidak ada selector yang kalah. Masalahnya justru aturan yang menang telak dan menetapkan warna yang tidak semestinya ditetapkan.