Setelah kita mempelajari berbagai teknik positioning, sering kali kita mengalami elemen yang saling tumpang tindih. Di sinilah properti z-index berperan. Z-index menentukan urutan tumpukan (stacking order) elemen yang diposisikan (non-static) pada sumbu Z (kedalaman layar).
Apa Itu Z-Index?
Z-index adalah properti CSS yang mengatur posisi vertikal (kedalaman) elemen pada tumpukan. Semakin besar nilai z-index, semakin di depan (dekat pengguna). Semakin kecil nilai z-index, semakin di belakang. Properti ini hanya berlaku untuk elemen yang memiliki position selain static (relative, absolute, fixed, sticky).
.box {
position: relative; /* atau absolute, fixed, sticky */
z-index: 10; /* angka, bisa negatif, auto adalah default */
}
Aturan:
- Elemen dengan z-index lebih besar akan menutupi elemen dengan z-index lebih kecil.
- Z-index hanya berpengaruh pada elemen non-static.
- Nilai z-index bisa positif, nol, atau negatif.
- Nilai default adalah
auto(sama dengan 0 dalam konteks stacking context).
1. Z-Index Dasar (Angka Positif)
Kotak dengan z-index lebih tinggi akan tampil di atas kotak dengan z-index lebih rendah.
Contoh:
<style>
.box {
position: relative;
width: 150px;
height: 150px;
color: white;
display: flex;
align-items: center;
justify-content: center;
}
.box1 { background: #3b82f6; top: 0; left: 0; z-index: 1; }
.box2 { background: #ef4444; top: -50px; left: 30px; z-index: 2; }
.box3 { background: #22c55e; top: -100px; left: 60px; z-index: 3; }
</style>
<div class="box box1">z-index: 1</div>
<div class="box box2">z-index: 2</div>
<div class="box box3">z-index: 3</div>
2. Z-Index Negatif
Z-index negatif akan menempatkan elemen di belakang elemen lain (termasuk background parent).
Contoh:
<style>
.parent {
position: relative;
background: #f0f4f8;
padding: 20px;
border: 2px solid #3b82f6;
width: 300px;
height: 150px;
}
.child {
position: absolute;
background: #ef4444;
color: white;
padding: 10px;
bottom: 0;
right: 0;
z-index: -1;
}
</style>
<div class="parent">
Parent
<div class="child">z-index: -1 (di belakang parent)</div>
</div>
Elemen dengan z-index negatif berada di belakang parent.
3. Stacking Context (Konteks Tumpukan)
Stacking context adalah hirarki tumpukan lokal di mana z-index dibandingkan. Setiap stacking context independen. Beberapa cara membentuk stacking context baru:
position: relative/absolute/fixed/stickydenganz-indexbukanauto.opacitykurang dari 1.transform,filter,perspective,clip-path, dll.isolation: isolate.
Contoh Stacking Context:
<style>
.context {
position: relative;
z-index: 1;
background: #f0f4f8;
padding: 20px;
margin: 20px;
}
.inner-high {
position: absolute;
background: #3b82f6;
color: white;
padding: 10px;
top: 40px;
left: 40px;
z-index: 999;
}
.outer-high {
position: relative;
background: #ef4444;
color: white;
padding: 10px;
margin: 50px 0 0 0;
z-index: 2;
}
</style>
<div class="context">
Context A (z-index: 1)
<div class="inner-high">Inner z=999</div>
</div>
<div class="outer-high">Context B (z-index: 2)</div>
Meskipun inner memiliki z-index 999, ia tetap di bawah Context B karena berada dalam stacking context A yang berbeda (z-index Context A < z-index Context B).
- Z-index hanya membandingkan elemen dalam stacking context yang sama.
- Elemen dengan stacking context baru bertindak sebagai "dunia kecil" sendiri.
- Untuk mengatasi masalah z-index, perhatikan apakah ada stacking context yang membatasi.
Contoh Proyek: Modal Overlay dengan Z-Index
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Z-Index - Demo Modal & Tooltip</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: #f0f4f8;
padding: 40px 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 4px 10px rgba(0,0,0,0.05);
}
h1 {
text-align: center;
margin-bottom: 20px;
}
/* Demo kartu dengan z-index saat hover */
.card-stack {
display: flex;
justify-content: center;
gap: 20px;
margin: 30px 0;
position: relative;
}
.stack-card {
background: #3b82f6;
color: white;
padding: 20px;
width: 150px;
height: 150px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
position: relative;
cursor: pointer;
}
.stack-card:hover {
transform: scale(1.05);
z-index: 10;
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
/* Tooltip dengan z-index */
.tooltip-demo {
position: relative;
display: inline-block;
margin: 20px;
cursor: pointer;
}
.tooltip-trigger {
background: #3b82f6;
color: white;
padding: 8px 16px;
border-radius: 6px;
}
.tooltip-box {
position: absolute;
bottom: 120%;
left: 50%;
transform: translateX(-50%);
background: #1e293b;
color: white;
padding: 6px 12px;
border-radius: 6px;
font-size: 12px;
white-space: nowrap;
z-index: 100;
display: none;
}
.tooltip-demo:hover .tooltip-box {
display: block;
}
/* Modal overlay */
.open-modal-btn {
background: #3b82f6;
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
cursor: pointer;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
display: none;
}
.modal-content {
background: white;
border-radius: 16px;
padding: 25px;
width: 90%;
max-width: 400px;
text-align: center;
z-index: 1001;
}
.close-modal {
background: #ef4444;
color: white;
border: none;
padding: 8px 20px;
border-radius: 6px;
cursor: pointer;
margin-top: 15px;
}
/* Overlap demo */
.overlap-demo {
position: relative;
height: 150px;
margin: 30px 0;
}
.overlap-box {
position: absolute;
width: 120px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
color: white;
border-radius: 8px;
}
.overlap-1 { background: #3b82f6; top: 0; left: 20px; z-index: 1; }
.overlap-2 { background: #22c55e; top: 20px; left: 50px; z-index: 2; }
.overlap-3 { background: #ef4444; top: 40px; left: 80px; z-index: 3; }
.info-box {
background: #eef2ff;
padding: 20px;
border-radius: 12px;
margin-top: 30px;
}
.info-box code {
background: #e2e8f0;
padding: 2px 6px;
border-radius: 4px;
font-family: monospace;
}
</style>
</head>
<body>
<div class="container">
<h1>Z-Index: Mengatur Tumpukan Elemen</h1>
<!-- Demo 1: Overlap dengan z-index -->
<div>
<h2>1. Overlap Sederhana dengan Z-Index</h2>
<div class="overlap-demo">
<div class="overlap-box overlap-1">z:1</div>
<div class="overlap-box overlap-2">z:2</div>
<div class="overlap-box overlap-3">z:3</div>
</div>
<p>Semakin besar z-index, semakin di depan.</p>
</div>
<hr>
<!-- Demo 2: Hover effect dengan z-index -->
<div>
<h2>2. Hover Meningkatkan Z-Index</h2>
<div class="card-stack">
<div class="stack-card">Card 1</div>
<div class="stack-card">Card 2</div>
<div class="stack-card">Card 3</div>
</div>
<p>Saat hover, card memiliki z-index: 10 sehingga muncul di atas card lain.</p>
</div>
<hr>
<!-- Demo 3: Tooltip dengan z-index tinggi -->
<div>
<h2>3. Tooltip dengan Z-Index Tinggi</h2>
<div class="tooltip-demo">
<span class="tooltip-trigger">Hover untuk tooltip</span>
<div class="tooltip-box">Tooltip dengan z-index: 100</div>
</div>
<p>Tooltip memiliki z-index tinggi agar tampil di atas elemen lain.</p>
</div>
<hr>
<!-- Demo 4: Modal dengan z-index sangat tinggi -->
<div>
<h2>4. Modal Overlay (Z-Index 1000)</h2>
<button class="open-modal-btn" id="openModal">Buka Modal</button>
<div id="modalOverlay" class="modal-overlay">
<div class="modal-content">
<h3>Modal Popup</h3>
<p>Modal ini memiliki z-index: 1000 untuk overlay, dan z-index: 1001 untuk konten.</p>
<button class="close-modal" id="closeModal">Tutup</button>
</div>
</div>
</div>
<div class="info-box">
<h3>Ringkasan Z-Index</h3>
<ul>
<li><code>z-index</code> mengatur tumpukan elemen pada sumbu Z.</li>
<li>Berlaku hanya untuk elemen dengan position non-static (relative, absolute, fixed, sticky).</li>
<li>Semakin besar nilai, semakin di depan (menutupi elemen lain).</li>
<li>Nilai bisa positif, nol, atau negatif.</li>
<li>Setiap stacking context baru membuat perbandingan z-index independen.</li>
<li>Gunakan z-index untuk modal, dropdown, tooltip, overlay, dan efek hover yang saling tumpuk.</li>
</ul>
</div>
</div>
<script>
const openBtn = document.getElementById('openModal');
const modal = document.getElementById('modalOverlay');
const closeBtn = document.getElementById('closeModal');
if (openBtn && modal && closeBtn) {
openBtn.addEventListener('click', () => {
modal.style.display = 'flex';
});
closeBtn.addEventListener('click', () => {
modal.style.display = 'none';
});
modal.addEventListener('click', (e) => {
if (e.target === modal) modal.style.display = 'none';
});
}
</script>
</body>
</html>
Hasil visual halaman demo:
Kesalahan Umum Pemula
- Lupa memberi position non-static pada elemen → Z-index tidak berpengaruh pada elemen static.
- Mengira z-index bisa dibandingkan antar stacking context berbeda → Z-index hanya valid dalam stacking context yang sama.
- Memberi z-index terlalu tinggi tanpa perlu → Bisa menyebabkan masalah sulit di-debug.
- Tidak memahami stacking context → Sering bingung mengapa z-index tidak berfungsi.
- Menggunakan z-index negatif tanpa memahami konsekuensi → Bisa membuat elemen berada di belakang parent atau background.
- Buka Developer Tools (F12) → inspect elemen → lihat tab Computed → cek nilai z-index dan stacking context.
- Gunakan panel "Layers" di Chrome DevTools untuk memvisualisasikan tumpukan.
- Untuk mengatasi z-index tidak berfungsi, pastikan elemen memiliki position selain static.
Latihan Singkat
- Buat tiga kotak dengan position absolute yang saling tumpang tindih, atur z-index berbeda.
- Buat efek hover pada kartu yang meningkatkan z-index dan scale.
- Buat tooltip custom dengan z-index tinggi.
- Buat modal overlay dengan z-index 1000 dan konten modal z-index 1001.
- Coba buat stacking context dengan opacity atau transform, lalu bandingkan z-index.
Intisari Hari Ini
- z-index mengatur tumpukan elemen pada sumbu Z (kedalaman).
- Hanya berlaku untuk elemen dengan position non-static (relative, absolute, fixed, sticky).
- Nilai lebih besar → lebih depan, nilai lebih kecil → lebih belakang.
- Nilai bisa positif, nol, atau negatif.
- Stacking context membatasi perbandingan z-index dalam lingkup lokal.
- Gunakan z-index untuk modal, tooltip, dropdown, overlay, dan efek hover tumpuk.
- Buat 3 kartu dalam posisi absolute atau relative yang saling tumpuk (seperti kartu remi).
- Saat hover pada kartu, kartu tersebut menjadi paling depan (z-index tertinggi) dan sedikit membesar.
- Buat tooltip yang muncul saat hover pada tombol, tooltip harus di atas kartu.
- Buat modal popup yang dapat dibuka, dengan overlay gelap di belakangnya.
- Modal harus memiliki z-index tertinggi di halaman.
- Tambahkan kotak penjelasan yang menerangkan stacking context mana yang terbentuk dan bagaimana z-index diterapkan.
Selamat mencoba!
Artikel Sebelumnya: CSS Dasar #21 - Position Fixed dan Sticky
Artikel Selanjutnya: CSS Dasar #23 - Pengenalan Flexbox: display: flex, flex-direction
