z-index CSS: Mengatur Elemen Mana yang Tampil di Depan

z-index menentukan elemen mana yang muncul di depan saat saling bertumpuk. Pelajari cara kerja penumpukan, kenapa z-index kadang tidak berfungsi, apa itu stacking context, dan cara membereskan bug-nya.

Diterbitkan 1 Agustus 202611 menit bacaOleh ACY Partner Indonesia
z-index CSS — mengatur urutan tumpukan elemen yang saling menutupi
300 × 250Slot Iklan TersediaPasang iklan Anda di sini

Kebanyakan elemen di sebuah halaman duduk manis berdampingan atau bertumpuk ke bawah — mereka tidak saling menutupi. Tapi begitu kamu mulai membuat menu dropdown, dialog modal, tooltip, header yang menempel saat di-scroll, atau apa pun yang mengambang di atas konten lain, elemen mulai saling tumpang tindih. Dan saat dua elemen menempati titik yang sama, browser harus memutuskan mana yang sebenarnya kamu lihat di depan.

Keputusan itulah yang disebut urutan tumpukan (stacking order), dan z-index adalah cara kamu mengendalikannya. Property-nya kecil, tapi reputasinya bikin pusing — orang menyetel z-index: 9999 tapi tetap tidak ngefek, dan mereka tidak paham kenapa. Setelah selesai membaca artikel ini, kamu bakal paham persis bagaimana penumpukan bekerja, kenapa z-index kadang cuek sama perintahmu, dan bagaimana caranya berhenti berkelahi dengannya. Yuk kita mulai.

Dimensi ketiga: sumbu z

Sebuah halaman web punya dua dimensi yang jelas terlihat: mendatar (sumbu x) dan tegak (sumbu y). Nah, z-index mengurusi dimensi ketiga yang tak kasat mata — sumbu z, yang arahnya keluar dari layar menuju ke arahmu. Anggap saja ini soal kedalaman, atau “seberapa dekat sebuah elemen ke wajahmu”.

Saat elemen saling bertumpuk, yang posisinya lebih tinggi di sumbu z akan menutupi yang ada di belakangnya. Nilai z-index yang lebih besar berarti “lebih dekat ke penonton”, jadi dialah yang menang dan tampil di atas:

.behind {
  z-index: 1;
}

.in-front {
  z-index: 2;   /* angka lebih besar menang — tampil di atas */
}

Itulah seluruh model berpikirnya: angka lebih besar, makin di depan. Masalahnya, z-index tidak bekerja di mana saja, dan tidak selalu bertingkah sesuai apa yang angkanya tunjukkan. Dua kejutan inilah yang sering bikin orang tersandung — jadi mari kita bereskan satu per satu.

Aturan pertama: z-index butuh positioning

Inilah jebakan yang hampir selalu menjebak orang di percobaan pertamanya. Secara bawaan, z-index tidak melakukan apa-apa pada elemen biasa yang posisinya static. Kamu bisa menyetel z-index: 9999 dan menyaksikannya sama sekali tanpa efek.

Supaya z-index mau bekerja, elemennya butuh nilai position selain bawaan static — artinya relative, absolute, fixed, atau sticky:

.box {
  z-index: 5;        /* diabaikan — position masih static */
}

.box {
  position: relative;  /* sekarang z-index baru boleh bekerja */
  z-index: 5;          /* nah, ini baru ngefek */
}

Jadi aturannya sederhana: z-index cuma berlaku untuk elemen yang punya posisi. Kalau z-index-mu kelihatan sama sekali tidak berpengaruh, inilah hal pertama yang harus kamu cek — sembilan dari sepuluh kasus, ternyata elemennya memang belum dikasih position.

Selalu pasangkan z-index dengan position

Setiap kali kamu menulis z-index, pastikan elemen yang sama punya position berupa relative, absolute, fixed, atau sticky. z-index tanpa positioning akan diabaikan diam-diam — tidak ada pesan error, dia cuma tidak melakukan apa-apa. Membiasakan menulis keduanya berbarengan bakal menyelamatkanmu dari banyak momen melongo ke layar tanpa tahu salahnya di mana.

Kalau kamu masih belum mantap soal beda position: relative, absolute, dan fixed, itu topik tersendiri yang layak dibaca terpisah — tapi untuk urusan z-index, yang perlu kamu tahu cuma satu: mana pun dari ketiganya akan mengeluarkan elemen dari status static sehingga z-index bisa bekerja.

Apa yang terjadi tanpa z-index sama sekali

Sebelum buru-buru pakai z-index, ada baiknya kamu paham dulu bagaimana browser menumpuk elemen ketika kamu tidak menyetelnya. Elemen yang saling tumpang tindih tetap punya urutan — z-index cuma alat untuk menimpa urutan itu.

Aturan bawaannya, secara garis besar, adalah urutan di kode (source order): elemen yang muncul belakangan di HTML akan menumpuk di atas elemen yang ditulis lebih dulu. Jadi kalau dua kotak yang sudah dipositioning saling tumpuk dan keduanya tidak punya z-index, yang ditulis lebih bawah di markup-lah yang menang:

<div class="box first">Pertama</div>
<div class="box second">Kedua</div>
.box {
  position: absolute;
  width: 150px;
  height: 150px;
}
.first  { top: 0;   left: 0;   background: tomato; }
.second { top: 40px; left: 40px; background: skyblue; }

Di sini .second menutupi .first dan duduk di atasnya — murni karena dia datang belakangan di HTML. Tanpa z-index sama sekali. Sering kali ini sudah persis seperti yang kamu mau, jadi kamu memang tidak butuh z-index. Kamu baru perlu menyentuhnya ketika urutan kode tidak memberikan susunan lapisan yang kamu inginkan.

Menentukan urutan tumpukan secara eksplisit

Sekarang mari kita benar-benar pakai z-index. Misalkan kamu punya tiga kartu yang saling tumpuk, dan kamu mau salah satu tertentu ada di depan, tak peduli urutannya di kode:

.card {
  position: absolute;
}
.card-a { z-index: 1; }
.card-b { z-index: 3; }   /* yang ini jadi paling depan */
.card-c { z-index: 2; }

Browser mengurutkannya berdasarkan z-index: card-b (3) paling depan, lalu card-c (2), lalu card-a (1) paling belakang. Angka aslinya tidak penting — yang penting cuma urutan relatifnya. z-index: 3 mengalahkan z-index: 2, sama persis seperti z-index: 300 mengalahkan z-index: 200. Tidak ada hadiah untuk angka besar.

Kamu juga bisa memakai nilai negatif untuk mendorong sebuah elemen ke belakang tetangga-tetangganya:

.background-shape {
  position: absolute;
  z-index: -1;   /* duduk di belakang konten di sekitarnya */
}

Ini berguna untuk bentuk dekoratif atau grafis latar yang seharusnya berada di bawah teks dan tidak mengganggu klik.

Tahan refleks z-index: 9999

Saat sebuah lapisan tak mau maju ke depan, solusi yang menggoda adalah menempelkan angka raksasa seperti z-index: 9999. Kadang berhasil, tapi itu cuma tambal sulam: kamu akhirnya terjebak perlombaan angka di mana setiap komponen baru butuh angka yang lebih besar lagi, dan tak ada yang tahu nilai mana yang aman. Kebanyakan kasus, masalah aslinya bukan di angka sama sekali — melainkan stacking context, yang sebentar lagi kita bahas. Beresin itu, dan nilai z-index yang kecil dan masuk akal sudah lebih dari cukup.

Sumber kebingungan yang sesungguhnya: stacking context

Inilah konsep yang menjelaskan semua bug z-index yang bikin garuk-garuk kepala. Namanya stacking context, dan begitu kamu paham, z-index berhenti terasa seperti undian.

Stacking context adalah sekelompok elemen yang berdiri sendiri dan menumpuk bersama sebagai satu kesatuan. Inti pentingnya: nilai z-index hanya dibandingkan di dalam stacking context yang sama. Elemen di dalam satu context tidak akan pernah bisa melompat ke depan elemen di context lain yang lebih tinggi — sebesar apa pun z-index-nya.

Bayangkan saja seperti lantai di dalam sebuah gedung. Di dalam satu lantai, kamu bebas menata ulang perabotan sesukamu. Tapi kursi di lantai dua selalu berada di bawah apa pun yang ada di lantai tiga, bahkan kalau kursi itu kamu taruh di atas tumpukan yang sangat tinggi. Tumpukan tinggi itu (alias z-index-mu) hanya berlaku di lantainya sendiri.

Akar halaman (elemen <html>) adalah stacking context paling atas. Tapi — dan ini bagian krusialnya — banyak property CSS umum yang diam-diam membuat stacking context baru. Beberapa pemicunya yang biasa:

  • Elemen dengan position yang disetel (relative/absolute/fixed/sticky) dan nilai z-index selain auto.
  • position: fixed atau position: sticky (keduanya membuat context sendiri begitu saja).
  • opacity yang kurang dari 1.
  • Nilai transform, filter, perspective, clip-path, atau mask.
  • will-change yang menyebut salah satu property di atas.
  • isolation: isolate (yang ini kita bahas di bawah — yang ini disengaja).

Daftar itulah penyebab z-index terasa seperti kena guna-guna. Kamu menyetel z-index anak jadi 9999, tapi induknya punya opacity: 0.99 atau sebuah transform, yang menjebak si anak di dalam stacking context berprioritas rendah. Si anak sekarang tidak bisa kabur melewati elemen-elemen di luar context itu, berapa pun angka yang kamu kasih.

Contoh nyata bug stacking context

Mari kita buat itu jadi konkret, karena inilah pusing kepala z-index yang paling sering muncul:

<div class="parent">
  <div class="modal">Aku mau di atas segalanya!</div>
</div>
<div class="other-stuff">Konten lain</div>
.parent {
  position: relative;
  transform: translateY(0);   /* ⚠️ ini membuat stacking context */
}
.modal {
  position: absolute;
  z-index: 9999;              /* raksasa — tapi terjebak di dalam .parent */
}
.other-stuff {
  position: relative;
  z-index: 1;
}

Kamu pasti mengira .modal dengan z-index: 9999 bakal melibas .other-stuff yang z-index-nya cuma 1. Nyatanya tidak. transform di .parent membuat stacking context baru, sehingga seluruh rentang z-index milik .modal sekarang terkurung di dalam .parent. Dibandingkan dunia di luar, .parent secara keseluruhan menumpuk di level yang rendah — dan .modal terpaksa ikut terseret bersamanya.

Solusinya hampir tidak pernah berupa angka yang lebih besar. Yang benar, kamu menghapus property yang membuat context tak diinginkan itu, atau kamu menata ulang struktur supaya elemen yang harus di depan tidak terjebak di dalam context rendah — misalnya dengan memindahkan modal ke level paling atas halaman (pola yang umum dipakai untuk modal dan tooltip).

Membuat stacking context dengan sengaja: isolation

Ada kalanya kamu justru ingin stacking context baru — untuk memagari sebuah komponen supaya nilai z-index di dalamnya tidak bocor keluar dan bentrok dengan sisa halaman. Cara paling bersih dan paling jelas niatnya adalah property isolation:

.widget {
  isolation: isolate;   /* stacking context baru, tanpa efek samping */
}

Kenapa ini lebih enak daripada alternatif lain? Kamu memang bisa memaksa stacking context dengan opacity: 0.999 atau transform: translateZ(0), tapi itu trik akal-akalan — keduanya mengubah cara render, kadang bikin teks jadi buram, dan menunjukkan niat yang salah. isolation: isolate cuma melakukan satu hal: membuat stacking context, tanpa efek samping visual apa pun. Saat kamu membangun komponen yang bisa dipakai ulang dan ingin nilai z-index-nya rapi terkurung di dalam, inilah alatnya.

Sistem pelapisan yang praktis

Di proyek nyata, angka z-index yang berserakan sembarangan akan jadi mimpi buruk untuk dipelihara. Kebiasaan sederhana yang awet adalah mendefinisikan sekelompok kecil lapisan yang diberi nama, lalu konsisten memakainya — dan pakai CSS custom property biar gampang dibaca:

:root {
  --z-base:     1;
  --z-dropdown: 10;
  --z-sticky:   20;
  --z-overlay:  30;
  --z-modal:    40;
  --z-toast:    50;
}

.dropdown { z-index: var(--z-dropdown); }
.modal    { z-index: var(--z-modal); }
.toast    { z-index: var(--z-toast); }

Sekarang ada hierarki yang jelas dan terdokumentasi: toast mengalahkan modal, modal mengalahkan overlay, overlay mengalahkan header yang sticky, dan seterusnya. Tidak ada lagi yang perlu menebak-nebak apakah 47 lebih besar dari angka ajaib lain yang nyempil di tiga file berbeda. Saat butuh lapisan baru, tinggal sisipkan ke daftar di posisi yang tepat. Disiplin kecil ini membunuh sebagian besar kekacauan z-index sebelum sempat dimulai.

Sisakan jarak yang lega

Perhatikan, lapisannya naik dengan kelipatan sepuluh (10, 20, 30…), bukan satu per satu. Tujuannya supaya nanti ada ruang untuk menyelipkan lapisan baru di antara dua lapisan yang sudah ada tanpa harus menomori ulang semuanya. Alasannya mirip kenapa dulu orang menomori baris program BASIC dengan kelipatan sepuluh — ada ruang napas untuk sisipan.

Cara mendebug z-index yang keras kepala

Saat sebuah lapisan tak mau pindah ke tempat yang kamu mau, tahan dorongan untuk menaikkan angkanya. Lebih baik telusuri daftar pemeriksaan singkat berikut:

  1. Apakah elemennya sudah dipositioning? Kalau position-nya masih static, z-index diabaikan. Inilah penyebab yang paling sering muncul.
  2. Telusuri ke atas, ke para induknya. Cek tiap induk apakah punya transform, filter, opacity di bawah 1, position: fixed/sticky, atau will-change. Salah satunya bisa membuat stacking context yang menjebak elemenmu.
  3. Bandingkan dalam context yang sama. Dua nilai z-index baru saling adu kalau berada di stacking context yang sama. Kalau tidak, yang dibandingkan adalah context-nya, bukan angkamu.
  4. Pertimbangkan memindahkan elemennya. Untuk hal yang wajib ada di atas segalanya — modal, tooltip, dropdown — solusi yang paling kokoh sering kali adalah me-render-nya di level paling atas halaman, di luar context mana pun yang menjebak, ketimbang terus mengejar angka yang makin besar.

Developer tools di browser sangat membantu di sini: banyak di antaranya menampilkan stacking context dan membiarkanmu memeriksa z-index final dari elemen mana pun, yang mengubah tebak-tebakan jadi diagnosis cepat.

Penutup

z-index itu kecil tapi licin — dan hampir semua misterinya berasal dari satu konsep, yaitu stacking context. Berikut semua yang layak kamu ingat:

  • Sumbu z mengarah keluar dari layar menuju ke arahmu; z-index yang lebih tinggi duduk lebih dekat ke penonton, jadi dia tampil di atas.
  • z-index cuma bekerja pada elemen yang dipositioning (relative, absolute, fixed, atau sticky) — pada elemen static dia tidak melakukan apa-apa.
  • Tanpa z-index, elemen yang bertumpuk disusun berdasarkan urutan di kode (yang lebih bawah di HTML menang).
  • Yang penting cuma urutan relatif nilai z-index; 9999 tidak lebih kuat dari 3 kalau tidak ada apa pun di antaranya.
  • Stacking context adalah kelompok tumpukan yang berdiri sendiri. Nilai z-index cuma dibandingkan di dalam context yang sama — sebuah elemen tidak bisa kabur dari context-nya, setinggi apa pun angkanya.
  • Pemicu umum context baru: transform, filter, opacity < 1, position: fixed/sticky, dan yang disengaja isolation: isolate.
  • Pakai sistem pelapisan kecil yang diberi nama dengan jarak yang lega ketimbang angka sembarangan, dan debug dengan mengecek positioning lebih dulu, lalu menelusuri ke atas ke para induk untuk mencari stacking context yang tersembunyi.

Setelah kamu akrab dengan stacking context, z-index berhenti jadi tebak-tebakan — kamu bakal langsung mengenali jebakannya, membenahi hal yang benar, lalu lanjut. Kalau kamu ingin menyegarkan lagi bagaimana positioning dan tumpang-tindih cocok ke gambaran besarnya, ada baiknya menengok kembali box model CSS dan alat tata letak yang sudah kamu kenal seperti Flexbox dan Grid — keduanya menentukan di mana elemen berada, sementara z-index menentukan siapa yang menang saat mereka saling menutupi.

Tag:cssfrontendz-indexstacking contexttata letakmenengah
728 × 90Slot Iklan TersediaPasang iklan Anda di sini

Artikel Terkait

Lihat Semua Artikel

Artikel yang Mungkin Kamu Suka

Apa Itu Framework Frontend? — chip kode dengan tag komponen
Frontend / Dasar

Apa Itu Framework Frontend?

Penjelasan ramah untuk pemula tentang apa itu framework frontend, kenapa mereka ada, masalah apa yang mereka selesaikan dibanding JavaScript biasa, dan kapan kamu memang sebaiknya memakainya.

20 Sep 20268 menit baca
Sampul fundamentals frontend bertuliskan Apa Itu Frontend dan HTML + CSS + JS
Frontend / Dasar

Apa Itu Frontend Development?

Panduan ramah pemula tentang frontend development: bagian website yang kamu lihat dan klik secara langsung. Pahami cara kerja HTML, CSS, dan JavaScript, serta bedanya frontend dengan backend.

20 Sep 20268 menit baca
Ilustrasi sampul untuk Apa yang Dikerjakan Frontend Developer
Frontend / Dasar

Apa yang Dikerjakan Frontend Developer: Panduan untuk Pemula

Penjelasan ramah pemula tentang apa yang sebenarnya dikerjakan frontend developer setiap hari: mengubah desain jadi antarmuka yang berfungsi, membangun UI yang bisa dipakai ulang, sampai urusan responsif, aksesibilitas, dan kecepatan.

20 Sep 20269 menit baca
Kartu judul bertuliskan Styling dan Interaktivitas di atas latar biru gelap ACY Partner
Frontend / Dasar

Cara Kerja Styling dan Interaktivitas

Penjelasan ramah pemula soal bagaimana CSS menyulap HTML polos jadi tampilan rapi, dan bagaimana JavaScript menambahkan perilaku — pola berpikir struktur, gaya, perilaku saat membangun halaman web.

20 Sep 20268 menit baca
Tiga lapisan front-end menyatu di satu halaman web
Frontend / Dasar

Cara HTML, CSS, dan JavaScript Bekerja Bersama

Panduan praktis untuk pemula: bikin satu tombol kecil, beri struktur dengan HTML, tampilan dengan CSS, dan perilaku dengan JavaScript, lalu lihat ketiga lapisan ini bekerja sama di halaman nyata.

20 Sep 20268 menit baca
Sampul ikhtisar praktik terbaik frontend
Frontend / Dasar

Ikhtisar Praktik Terbaik Frontend

Peta ringkas tentang apa itu frontend yang baik — HTML bermakna, CSS rapi, JavaScript secukupnya, desain responsif, performa, dan progressive enhancement, lengkap dengan arahan untuk mendalaminya.

20 Sep 20268 menit baca