Pernahkah Anda menyetel z-index: 99999 pada sebuah elemen di CSS Anda, dan elemen tersebut tidak muncul di atas elemen lainnya? Nilai sebesar itu akan dengan mudah menempatkan elemen tersebut secara visual di atas elemen lainnya, dengan asumsi semua elemen berbeda disetel pada nilai yang lebih rendah atau tidak disetel sama sekali. Halaman web biasanya direpresentasikan dalam ruang dua dimensi; namun, dengan menerapkan properti CSS tertentu, bidang sumbu z imajiner diperkenalkan untuk menyampaikan kedalaman. Bidang ini tegak lurus terhadap layar, dan dari situ, pengguna melihat urutan elemen, satu di atas yang lain. Ide di balik sumbu z imajiner, yaitu persepsi pengguna terhadap elemen bertumpuk, adalah bahwa properti CSS yang membuatnya digabungkan untuk membentuk apa yang kita sebut konteks bertumpuk. Kita akan membahas tentang bagaimana elemen “ditumpuk” pada halaman web, apa yang mengontrol urutan penumpukan, dan pendekatan praktis untuk “melepaskan” elemen bila diperlukan. Tentang Menumpuk Konteks Bayangkan halaman web Anda sebagai sebuah meja. Saat Anda menambahkan elemen HTML, Anda meletakkan potongan kertas, satu demi satu, di atas meja. Potongan kertas terakhir yang ditempatkan setara dengan elemen HTML yang terakhir ditambahkan, dan berada di atas semua kertas lain yang ditempatkan sebelumnya. Ini adalah alur dokumen normal, bahkan untuk elemen bertumpuk. Meja itu sendiri mewakili konteks penumpukan akar, yang dibentuk oleh elemen , yang berisi semua folder lainnya. Sekarang, properti CSS tertentu ikut berperan. Properti seperti posisi (dengan indeks-z), opacity, transform, dan mengandung) bertindak seperti folder. Folder ini mengambil elemen dan semua turunannya, mengekstraknya dari tumpukan utama, dan mengelompokkannya ke dalam sub-tumpukan terpisah, menciptakan apa yang kita sebut konteks penumpukan. Untuk elemen yang diposisikan, ini terjadi ketika kita mendeklarasikan nilai indeks-z selain otomatis. Untuk properti seperti opacity, transform, dan filter, konteks penumpukan dibuat secara otomatis ketika nilai tertentu diterapkan.
Coba pahami ini: Sekali selembar kertas (yaitu, elemen anak) berada di dalam folder (yaitu, konteks tumpukan induknya), kertas tersebut tidak akan pernah bisa keluar dari folder itu atau ditempatkan di antara kertas-kertas di folder yang berbeda. Indeks-z-nya sekarang hanya relevan di dalam foldernya sendiri.
Pada ilustrasi di bawah, Kertas B kini berada dalam konteks penumpukan Folder B, dan hanya dapat dipesan dengan kertas lain di dalam folder tersebut.
Bayangkan, jika Anda mau, Anda memiliki dua folder di meja Anda:
.folder-a { indeks-z: 1; } .folder-b { indeks-z: 2; }
Mari perbarui markupnya sedikit. Di dalam Folder A ada halaman khusus, z-index: 9999. Di dalam Folder B ada halaman biasa, z-index: 5.
.halaman khusus { indeks-z: 9999; } .halaman biasa { indeks-z: 5; }
Halaman mana yang paling atas? Ini adalah halaman .plain di Folder B. Browser mengabaikan kertas anak dan menumpuk kedua folder terlebih dahulu. Ia melihat Folder B (indeks-z: 2) dan menempatkannya di atas Folder A (indeks-z: 1) karena kita tahu bahwa dua lebih besar dari satu. Sementara itu, halaman .special-page yang disetel ke z-index: 9999 berada di bagian paling bawah tumpukan meskipun z-index-nya disetel ke nilai setinggi mungkin. Konteks yang bertumpuk juga dapat disarangkan (folder di dalam folder), sehingga menciptakan “pohon keluarga”. Prinsip yang sama juga berlaku: seorang anak tidak akan pernah bisa lepas dari folder orangtuanya. Sekarang setelah Anda memahami bagaimana konteks penumpukan berperilaku seperti folder yang mengelompokkan dan menyusun ulang lapisan, ada baiknya bertanya: mengapa properti tertentu — seperti transformasi dan opacity — membuat konteks tumpukan baru? Masalahnya: properti ini tidak membuat konteks bertumpuk karena tampilannya; mereka melakukannya karena cara kerja browser. Saat Anda menerapkan transformasi, opasitas, filter, atau perspektif, Anda memberi tahu browser, “Hei, elemen ini mungkin bergerak, berputar, atau memudar, jadi bersiaplah!”
Saat Anda menggunakan properti ini, browser membuat konteks tumpukan baru untuk mengelola rendering dengan lebih efisien. Hal ini memungkinkan browser menangani animasi, transformasi, dan efek visual secara independen, sehingga mengurangi kebutuhan untuk menghitung ulang bagaimana elemen-elemen ini berinteraksi dengan halaman lainnya. Anggap saja browser berkata, "Saya akan menangani folder ini secara terpisah sehingga saya tidak perlu merombak seluruh tabel setiap kali ada perubahan di dalamnya." Tapi adaefek samping. Setelah browser mengangkat elemen ke dalam lapisannya sendiri, browser harus “meratakan” semua yang ada di dalamnya, menciptakan konteks penumpukan baru. Ini seperti mengambil folder dari meja untuk ditangani secara terpisah; semua yang ada di dalam folder itu dikelompokkan, dan browser sekarang memperlakukannya sebagai satu kesatuan ketika memutuskan apa yang ada di atasnya. Jadi, meskipun properti transformasi dan opacity mungkin tidak tampak memengaruhi cara elemen ditumpuk secara visual, hal tersebut berpengaruh, dan ini untuk pengoptimalan performa. Beberapa properti CSS lainnya juga dapat membuat konteks bertumpuk karena alasan serupa. MDN menyediakan daftar lengkap jika Anda ingin menggali lebih dalam. Ada cukup banyak, yang hanya menggambarkan betapa mudahnya membuat konteks bertumpuk secara tidak sengaja tanpa menyadarinya. Masalah “Tidak Bertumpukan”. Masalah penumpukan dapat muncul karena berbagai alasan, namun ada beberapa alasan yang lebih umum dibandingkan alasan lainnya. Komponen modal adalah pola klasik karena memerlukan pengalihan komponen menjadi "terbuka" pada lapisan atas di atas semua elemen lainnya, lalu menghapusnya dari lapisan atas saat "tertutup". Saya cukup yakin bahwa kita semua pernah mengalami situasi di mana kita membuka modal dan, apa pun alasannya, modal tersebut tidak muncul. Bukan karena tidak terbuka dengan benar, tetapi tidak terlihat di lapisan bawah konteks tumpukan. Hal ini membuat Anda bertanya-tanya “kenapa?” sejak Anda menetapkan:
.hamparan { posisi: tetap; /* membuat konteks bertumpuk */ indeks-z: 1; /* menempatkan elemen pada satu layer di atas segalanya */ sisipan: 0; lebar: 100%; tinggi: 100vh; meluap: tersembunyi; warna latar belakang: #00000080; }
Ini terlihat benar, tetapi jika elemen induk yang berisi pemicu modal adalah elemen anak dalam elemen induk lain yang juga disetel ke indeks-z: 1, maka secara teknis menempatkan modal dalam sublapisan yang dikaburkan oleh folder utama. Mari kita lihat skenario spesifik tersebut dan beberapa kendala umum lainnya dalam konteks penumpukan. Saya pikir Anda tidak hanya akan melihat betapa mudahnya membuat konteks bertumpuk secara tidak sengaja, tetapi juga bagaimana salah mengelolanya. Selain itu, cara Anda kembali ke kondisi terkelola bergantung pada situasinya. Skenario 1: Modal yang Terjebak
Anda dapat segera melihat modal Anda terperangkap di lapisan tingkat rendah dan mengidentifikasi induknya. Ekstensi Peramban Pengembang cerdas telah membuat ekstensi untuk membantu. Alat seperti ekstensi Chrome “CSS Stacking Context Inspector” ini menambahkan tab indeks-z tambahan ke DevTools Anda untuk menampilkan informasi tentang elemen yang membuat konteks bertumpuk.
Ekstensi IDE Anda bahkan dapat menemukan masalah selama pengembangan dengan ekstensi seperti ini untuk VS Code, yang menyoroti potensi masalah konteks penumpukan langsung di editor Anda.
Menghapus Susun Dan Mendapatkan Kembali Kontrol Setelah kita mengidentifikasi akar permasalahannya, langkah selanjutnya adalah mengatasinya. Ada beberapa pendekatan yang dapat Anda ambil untuk mengatasi masalah ini, dan saya akan mencantumkannya secara berurutan. Namun, Anda dapat memilih siapa pun di level mana pun; tidak seorang pun dapat mengeluh atau menghalangi orang lain. Ubah Struktur HTML Ini dianggap sebagai perbaikan optimal. Agar Anda mengalami masalah konteks bertumpuk, Anda harus menempatkan beberapa elemen pada posisi yang lucu dalam HTML Anda. Merestrukturisasi halaman akan membantu Anda membentuk ulang DOM dan menghilangkan masalah konteks penumpukan. Temukan elemen yang bermasalah dan hapus dari elemen yang menjebak di markup HTML. Misalnya, kita dapat menyelesaikan skenario pertama, “The Trapped Modal,” dengan memindahkan .modal-container keluar dari header dan menempatkannya di elemen
dengan sendirinya.Konten ini memiliki indeks-z 2 dan tetap tidak mencakup modal.Tajuk
Konten Utama
Judul Modal
Sekarang, saya tidak ketinggalan apa pun. Saya mendapatkan posisi yang lebih baik berkat restrukturisasi DOM.
Saat Anda mengeklik tombol “Buka Modal”, modal diposisikan di depan segalanya sebagaimana mestinya. Lihat Skenario Pena 1: Modal yang Terjebak (Solusi) [bercabang] oleh Shoyombo Gabriel Ayomide. SesuaikanKonteks Penumpukan Induk Dalam CSS Bagaimana jika elemennya adalah elemen yang tidak dapat Anda pindahkan tanpa merusak tata letaknya? Lebih baik mengatasi masalah ini: orang tualah yang menentukan konteksnya. Temukan properti (atau properti) CSS yang bertanggung jawab untuk memicu konteks dan menghapusnya. Jika memiliki tujuan dan tidak dapat dihapus, berikan nilai indeks z induknya lebih tinggi daripada elemen saudaranya untuk mengangkat seluruh wadah. Dengan nilai indeks-z yang lebih tinggi, penampung induk berpindah ke atas, dan penampung turunannya tampak lebih dekat dengan pengguna. Berdasarkan apa yang kita pelajari dalam skenario “The Submerged Dropdown”, kita tidak bisa memindahkan dropdown dari navbar; itu tidak masuk akal. Namun, kita dapat meningkatkan nilai z-index pada container .navbar menjadi lebih besar dari nilai z-index elemen .content. .navbar { latar belakang: #333; /* indeks-z: 1; */ indeks-z: 3; posisi: relatif; }
Dengan perubahan ini, menu .dropdown sekarang muncul di depan konten tanpa masalah apa pun.
Lihat Skenario Pena 2: Dropdown Terendam (Solusi) [bercabang] oleh Shoyombo Gabriel Ayomide.
Coba Portal, Jika Menggunakan Kerangka
Dalam kerangka kerja seperti React atau Vue, Portal adalah fitur yang memungkinkan Anda merender komponen di luar hierarki induk normalnya di DOM. Portal seperti perangkat teleportasi untuk komponen Anda. Mereka memungkinkan Anda merender HTML komponen di mana pun dalam dokumen (biasanya langsung ke document.body) sambil menjaganya tetap terhubung secara logis ke induk aslinya untuk props, state, dan event. Ini sempurna untuk menghindari jebakan konteks yang bertumpuk karena keluaran yang diberikan benar-benar muncul di luar wadah induk yang bermasalah.
ReactDOM.createPortal(
Hal ini memastikan konten tarik-turun Anda tidak tersembunyi di balik induknya, meskipun induknya memiliki overflow: tersembunyi atau indeks-z yang lebih rendah. Dalam skenario "The Clipped Tooltip" yang kita lihat sebelumnya, saya menggunakan Portal untuk menyelamatkan tooltip dari overflow: klip tersembunyi dengan menempatkannya di badan dokumen dan memposisikannya di atas pemicu di dalam wadah. Lihat Skenario Pena 3: Tooltip Terpotong (Solusi) [bercabang] oleh Shoyombo Gabriel Ayomide. Memperkenalkan Konteks Penumpukan Tanpa Efek Samping Semua pendekatan yang dijelaskan di bagian sebelumnya ditujukan untuk “membongkar” elemen dari konteks penumpukan yang bermasalah, namun ada beberapa situasi di mana Anda benar-benar perlu atau ingin membuat konteks penumpukan. Membuat konteks penumpukan baru itu mudah, tetapi semua pendekatan memiliki efek samping. Yaitu, kecuali untuk menggunakan isolasi: isolasi. Saat diterapkan pada suatu elemen, konteks susun dari turunan elemen tersebut ditentukan secara relatif terhadap setiap turunan dan dalam konteks tersebut, bukan dipengaruhi oleh elemen di luarnya. Contoh klasiknya adalah menetapkan nilai negatif pada elemen tersebut, seperti indeks-z: -1. Bayangkan Anda memiliki komponen .card. Anda ingin menambahkan bentuk dekoratif yang berada di belakang teks .card, namun di atas latar belakang kartu. Tanpa konteks penumpukan pada kartu, z-index: -1 mengirimkan bentuk ke bagian bawah konteks penumpukan akar (seluruh halaman). Ini membuatnya menghilang di balik latar belakang putih .card: Lihat indeks z Pen Negatif (masalah) [bercabang] oleh Shoyombo Gabriel Ayomide. Untuk mengatasinya, kami mendeklarasikan isolasi: isolasi pada .card induk: Lihat indeks z Pen Negatif (solusi) [bercabang] oleh Shoyombo Gabriel Ayomide. Sekarang, elemen .card itu sendiri menjadi konteks bertumpuk. Ketika elemen turunannya — bentuk dekoratif yang dibuat pada elemen semu :before — memiliki indeks-z: -1, ia berada di bagian paling bawah dari konteks tumpukan induknya. Itu terletak sempurna di belakang teks dan di atas latar belakang kartu, sebagaimana dimaksud. Kesimpulan Ingat: saat indeks-z Anda tampak lepas kendali, ini adalah konteks penumpukan yang terjebak. Referensi
Konteks bertumpuk (MDN) Indeks-Z dan konteks susun (web.dev) “Cara Membuat Konteks Susun Baru dengan Properti Isolasi di CSS”, Natalie Pina “Apa-apaan ini, indeks-z??”, Josh Comeau
Bacaan Lebih Lanjut Tentang SmashingMag
“Mengelola CSS Z-Index Dalam Proyek Besar”, Steven Frieson “Header Lengket Dan Elemen Tinggi Penuh: Kombinasi yang Rumit”, Philip Braunen “Mengelola Z-Index Dalam Aplikasi Web Berbasis Komponen”, Pavel Pomerantsev “Properti CSS Indeks Z: Tampilan Komprehensif”, Louis Lazaris