CSS Dasar #22 - Z-Index: Mengatur Tumpukan Elemen

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).

Sintaks Z-Index:
.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>
z:1
z:2
z:3
Catatan: Z-index hanya membandingkan elemen dalam stacking context yang sama. Elemen dari stacking context berbeda bisa memiliki aturan sendiri.

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>
Parent
z-index: -1

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/sticky dengan z-index bukan auto.
  • opacity kurang 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>
Context A (z-index: 1)
Inner z=999
Context B (z-index: 2)

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).

Poin Penting Stacking Context:
  • 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:

Overlap Sederhana dengan Z-Index

z:1
z:2
z:3
Ringkasan: Z-index menentukan urutan tumpukan. Nilai lebih besar = lebih depan.

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.
Debugging Tips:
  • 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

  1. Buat tiga kotak dengan position absolute yang saling tumpang tindih, atur z-index berbeda.
  2. Buat efek hover pada kartu yang meningkatkan z-index dan scale.
  3. Buat tooltip custom dengan z-index tinggi.
  4. Buat modal overlay dengan z-index 1000 dan konten modal z-index 1001.
  5. 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.
Tantangan: Buat sebuah Halaman dengan Beberapa Elemen Overlay yang saling tumpang tindih! Persyaratan:
  • 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

Lebih baru Lebih lama

نموذج الاتصال