Dua elemen yang saling bertumpuk menimbulkan pertanyaan sederhana: siapa yang digambar di atas? Jawabannya bukan sekadar membandingkan nilai z-index, melainkan memahami stacking context — lingkup tempat urutan menggambar dihitung. Stacking context dibentuk oleh elemen tertentu, dan seluruh keturunannya terkurung di dalam lingkup tersebut. Pada Chapter ini kita memetakan properti apa saja yang membentuk context, membuktikan pengaruhnya dengan dua grup terisolasi, lalu berlatih menelusuri urutan lapisan di DevTools.

Aturan Menggambar dan Batas Lingkup #

Browser menggambar elemen dalam urutan yang pasti: latar dokumen terlebih dahulu, lalu konten alur, kemudian elemen positioned dan elemen dengan z-index dari yang terkecil. Perbandingan z-index hanya bermakna di antara elemen yang berada dalam stacking context yang sama. Ketika sebuah elemen membentuk context, seluruh isi di dalamnya — sejauh apa pun kedalaman keturunannya — diperlakukan sebagai satu kesatuan di luar.

Aturan lingkup inilah sumber kejutan yang paling sering dikeluhkan: anak dengan z-index: 999 tetap tampil di bawah elemen asing yang bernilai kecil, sebab 999 itu hanya berlaku di dalam context induknya. Pembentuk stacking context di antaranya:

  • elemen akar (html) — context paling luar;
  • elemen positioned dengan z-index selain auto;
  • elemen dengan opacity kurang dari 1;
  • elemen dengan transform, filter, perspective, atau clip-path;
  • elemen dengan isolation bernilai isolate;
  • elemen dengan mix-blend-mode selain normal, will-change yang menunjuk properti di atas, serta contain: layout atau contain: paint.

Contoh: Dua Grup Terisolasi #

Demo chapter ini menampilkan dua kartu yang saling menumpuk. Keduanya membawa isolation: isolate sehingga masing-masing menjadi stacking context mandiri. Di dalam Grup A kita menaruh chip dengan z-index: 99, sedangkan chip di Grup B hanya bernilai 1.

css
.grup-a,
.grup-b {
  position: relative;
  isolation: isolate;
}
.chip-a {
  position: absolute;
  z-index: 99;
}
.chip-b {
  position: absolute;
  z-index: 1;
}
html index.html
<section class="grup-a">Grup A
  <span class="chip-a">z-index 99</span>
</section>
<section class="grup-b">Grup B
  <span class="chip-b">z-index 1</span>
</section>

Hasil di Browser:

text
Kedua grup dicatat computed isolation: isolate sehingga masing-masing
menjadi stacking context. Chip A membawa position: absolute dengan
z-index: 99 dan chip B hanya z-index: 1, tetapi Grup B tetap
menggambar di atas Grup A: perbandingan dilakukan antar-context pada
level grup, bukan antara nilai z-index kedua chip. Kartu dengan
opacity: 0.5 pada demo juga membentuk context — anaknya yang
ber-z-index 5 tetap terkurung di dalam kartu.

Mari kita telaah pola ini baris demi baris:

  1. Baris 2–3 (position: relative + isolation: isolate): kedua grup menjadi lingkup tertutup. isolation dipilih karena bersih — tidak mengubah tampilan apa pun selain membentuk context.
  2. Baris 5–7 (chip A): nilai 99 hanya bertaruh di dalam Grup A. Di luar grup, chip A diwakili oleh posisi grupnya.
  3. Baris 9–11 (chip B): nilai 1 sama-sama lokal untuk Grup B.
  4. Urutan grup: karena kedua context berdiri sejajar di context akar, urutan menggambarnya mengikuti urutan DOM — Grup B yang ditulis belakangan menang.

Menelusuri Urutan Lapisan di DevTools #

Ketika elemen menolak naik ke atas, jangan menaikkan angka z-index lebih dulu. Buka DevTools: Chrome menyediakan panel Layers untuk memeriksa lapisan yang digambar, dan Firefox memiliki tampilan 3D (3D View) yang memvisualkan tumpukan elemen secara perspektif. Dari sana, telusuri rantai ancestor elemen bermasalah dan cari siapa yang membentuk context — biasanya satu properti seperti transform atau opacity pada pembungkus.