Tutorial CSS / z-index CSS dan Konteks Penumpukan

z-index mengontrol penumpukan dalam konteks penumpukan (stacking context) yang relevan daripada memberikan setiap elemen kedalaman global. Anak dengan z-index besar bisa tetap berada di belakang elemen dalam konteks leluhur yang lebih tinggi, dan z-index tidak dapat membatalkan pemotongan overflow.

Pisahkan pemposisian dari urutan penumpukan

Untuk membandingkan urutan tumpang tindih, kedua elemen harus benar-benar menempati area layar yang sama. Jika mereka sepenuhnya berada di kiri dan kanan, atau atas dan bawah, mengubah z-index tidak akan membuat perbedaan. Pertama, periksa posisi persegi panjang elemen di alat pengembang dan tentukan apakah ada area yang tumpang tindih. Untuk standar penempatan elemen yang tumpang tindih, periksa standar ruang dan koordinat dari position CSS: relative, absolute, fixed, dan sticky.

Posisi menentukan standar koordinat dan partisipasi aliran, sedangkan z-index menentukan posisi depan dan belakang saat tumpang tindih. Mengubah koordinat dengan top dan mengubah urutan dengan z-index adalah tugas yang berbeda. Contoh di bawah ini mempertahankan posisi badge dan kartu lalu hanya mengubah z-index dari induknya, sehingga Anda dapat membandingkan kedua fungsi tanpa mencampurnya.

z-index dapat diterapkan pada elemen yang diposisikan seperti relative·absolute, dan dapat digunakan untuk item Flex dan item Grid meskipun position: static. Jika Anda hanya menetapkan angka untuk blok aliran umum biasa dan mengharapkan efek, kondisi penerapannya mungkin tidak terpenuhi. Anda dapat memeriksa arti target dan nilai dalam deskripsi z-index MDN.

Bandingkan konteks penumpukan sebagai kelompok

Sebuah konteks penumpukan mengelompokkan keturunannya untuk perbandingan tumpukan eksternal. Jika induk kiri memiliki z-index: 1 dan kartu kanan memiliki z-index: 2, lencana anak dengan z-index: 9999 di dalam konteks kiri tidak bersaing langsung dengan kartu kanan. Kelompok induk tetap berada di bawahnya.

Left parent context: z-index 1
└ Child badge: z-index 9999
Right card context: z-index 2

Outside, compare parent 1 and card 2.

Menaikkan induk kiri ke z-index: 3 menempatkan seluruh konteksnya di atas kartu kanan pada 2. Lencana anak tetap memiliki nilai 9999 tetapi menjadi terlihat dalam tumpang tindih. Nomor leluhur dan keturunan tidak dijumlahkan untuk menghasilkan nilai global seperti 10000. Lihat MDN: Konteks penumpukan.

Identifikasi deklarasi yang membuat konteks

Kondisi perwakilan Buat konteks baru Yang perlu diperiksa
relative atau absolute + z-index bukan auto Ya 0 juga merupakan angka dan berbeda dari auto.
fixed atau sticky Ya Membuat konteks meskipun z-index adalah auto
Item Flex atau Grid + z-index bukan auto Ya Mungkin tanpa posisi
opacity kurang dari 1 Ya Mempengaruhi hubungan grup serta visibilitas
transform bukan none Ya Bahkan jika jumlah pergerakan adalah 0, itu berbeda dari nilai none
isolation: isolate Ya Cara sengaja membuat konteks terpisah

Tabel di atas adalah daftar kondisi yang sering ditemui dan bukan daftar semua kondisi pembuatan. Anda harus membedakan antara kasus di mana hanya relative yang ditentukan dan z-index adalah auto, dan kasus di mana z-index: 0 ditentukan untuk relative. Jika tumpang tindih telah berubah, periksa tidak hanya angkanya tetapi juga opacity atau transform yang baru ditambahkan ke leluhur.

Dalam konteks yang sama, Anda dapat membandingkan bagian depan dan belakang menggunakan angka z-index dari elemen yang memenuhi kondisi aplikasi. Namun, karena urutan keseluruhan gambar CSS memiliki beberapa tingkat, termasuk tingkat negatif, aliran normal, dan elemen yang diposisikan, jangan memperlakukan auto untuk semua elemen sebagai sama dengan angka 0 atau menghitung urutan halaman secara keseluruhan hanya berdasarkan angka. Praktik pembelajaran membatasi kondisi pada angka positif dan konteks induk yang eksplisit.

Bandingkan nilai z-index induk dan anak

Simpan kode di bawah ini sebagai stacking-context.html dan buka. Lencana ditempatkan 80-144px dari atas, dan kartu di kanan ditempatkan di area 110-230px, dengan tumpang tindih vertikal sebesar 34px. Posisi kiri dan kanan menggunakan rasio terhadap lebar induk untuk mempertahankan tumpang tindih pada ponsel. Induk dan item dihitung sebagai border-box dan dikonfigurasi untuk mencegah overflow yang tidak perlu di luar wadah.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>stacking-context.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.scene { position: relative; width: min(100%, 520px); height: 300px; background: #f1f4f7; }
 .left { position: absolute; z-index: 1; left: 0; top: 20px; width: 60%; height: 180px;
 padding: 16px; background: #ffe3b5; }
 .badge { position: absolute; z-index: 9999; left: 70%; top: 60px; width: 50%; height: 64px;
 padding: 8px; background: #f5a7cc; }
 .right { position: absolute; z-index: 2; left: 50%; top: 110px; width: 45%; height: 120px;
 padding: 12px; background: #9cd4f2; }
 .raised .left { z-index: 3; }
  </style>
</head>
<body>
<h1>Child and parent z-index values</h1><h2>Parent: 1; right card: 2</h2><div class="scene original"><div class="left">Left parent<div class="badge">Child badge<br>9999</div></div><div class="right">Right card<br>z-index: 2</div></div><h2>Parent: 3; right card: 2</h2><div class="scene raised"><div class="left">Left parent<div class="badge">Child badge<br>9999</div></div><div class="right">Right card<br>z-index: 2</div></div>
</body>
</html>

Di bagian pertama, lencana merah muda yang tumpang tindih tersembunyi oleh kartu biru, dan di bagian kedua, lencana merah muda terlihat di atas kartu biru. Satu-satunya perbedaan antara kedua zona adalah 1 dan 3 dari induk kiri. Diagram penjelasan berikut membandingkan kedua keadaan dengan posisi skematis yang tidak berubah. Ini bukan tangkapan layar browser.

Two overlapping schemes are the same: in parent context 1, card 2 partially covers the child with z-index 9999. When the parent context becomes 3, the child appears in front of the card.

  1. Hanya tingkatkan nomor .badge di bagian pertama menjadi 99999. Hubungan antara induk 1 dan kartu 2 tetap terjaga, sehingga bagian yang tumpang tindih tetap tertutupi oleh kartu. Kembalikan nomor menjadi 9999.
  2. Tambahkan aturan .original .left { z-index: 3; }. Badge akan naik di atas kartu tanpa mengubah koordinat. Setelah dikonfirmasi, hapus aturan yang ditambahkan.
  3. Di bagian pertama yang asli, hanya ubah z-index dari .left menjadi auto. Dalam contoh ini, tanpa properti penciptaan lainnya, induk kiri tidak membuat konteks terpisah, sehingga konteks badge dibandingkan dengan kartu luar. Pastikan badge terlihat di depan dan kembalikan nilainya menjadi 1.
  4. Persempit atau perlebar layar untuk memastikan badge dan kartu masih saling tumpang tindih. Karena perubahan numerik tidak terlihat saat koordinat terpisah, perbandingan harus dilakukan sambil mempertahankan area tumpang tindih.

Bedakan pemotongan overflow dari penumpukan

Jika leluhur memotong konten dengan overflow: hidden, bagian di luar batasnya tidak dapat dibuat terlihat lagi hanya dengan z-index tinggi. Jika itu berada di urutan depan tetapi tidak terlihat, Anda perlu menentukan apakah itu tertutup oleh elemen lain atau terpotong di batas leluhur. Simpan kode di bawah ini sebagai stacking-clip.html dan jalankan. Bahkan jika Anda meningkatkan z-index, jika terpotong di batas induk, periksa kondisi pemotongan untuk Overflow CSS, Pembungkusan Teks Panjang, dan Elipsis.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>stacking-clip.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.frame { position: relative; width: min(100%, 260px); height: 100px; overflow: hidden;
 border: 2px solid #789; background: #e8f5de; }
 .popup { position: absolute; z-index: 9999; left: 80%; top: 24px; width: 90px; height: 60px;
 padding: 8px; background: #f5a7cc; }
  </style>
</head>
<body>
<h1>A box that stays clipped at a higher z-index</h1><div class="frame">Parent boundary<div class="popup">Badge<br>9999</div></div><p>The right side of the badge extends beyond its parent's boundary.</p>
</body>
</html>
  1. Pastikan sisi kanan lencana terpotong di tepi induk. Bahkan jika Anda mengubah z-index menjadi 99999, bagian yang terpotong tidak muncul. Kembalikan angkanya menjadi 9999.
  2. Hanya mengubah overflow dari .frame menjadi visible. Koordinat dan angka lain tetap sama, tetapi area di luar batas terlihat. Setelah dibandingkan, kembalikan ke hidden.

Di layar nyata, menghapus overflow dapat mempengaruhi tujuan lain, seperti scrolling dan sudut melengkung. Pertama tentukan apakah pemotongan dimaksudkan, dan jika popup harus berada di luar batas, pindahkan struktur keluar dari induk yang memotong atau pertimbangkan metode tampilan terpisah sesuai kebutuhan. Jangan mengubah overflow semua induk sekaligus hanya karena menyembunyikan menu.

Ikuti urutan diagnostik

  1. Periksa apakah elemen benar-benar ada dan tidak tersembunyi karena display·visibility·opacity.
  2. Periksa posisi persegi panjang dari kedua elemen untuk melihat apakah ada area tumpang tindih yang sebenarnya.
  3. Mulai dari elemen target, lalu telusuri leluhurnya untuk menemukan deklarasi yang membuat konteks penumpukan. Tentukan induk bersama yang dibandingkan konteks bersaing.
  4. Tentukan apakah angka yang perlu diubah berada pada konteks anak atau konteks induk. Juga periksa elemen saudara yang terpengaruh dan sesuaikan nilainya hanya dalam rentang yang diperlukan.
  5. Jika Anda masih tidak melihatnya bahkan setelah mengubah urutan, periksa pemotongan seperti overflow·clip dan standar koordinat lainnya. Setelah menyelesaikan perbandingan, nilai yang dimodifikasi sementara dikembalikan ke nilai aslinya.

Z-index dari elemen biasa sebaiknya tidak dipandang sebagai cara untuk mengatasi lapisan tampilan terpisah, seperti dialog di lapisan atas, hanya dengan meningkatkan angkanya. Saat memecahkan masalah kartu dan lencana default, penting untuk terlebih dahulu memahami konteks induk sebenarnya dan pemotongan. Alih-alih terus meningkatkan angkanya, Anda bisa mengatur urutan yang diinginkan bahkan dengan nilai kecil dengan memeriksa grup mana yang dibandingkan.