Hiç CSS'nizdeki bir öğeye z-index: 99999 ayarladığınız halde diğer öğelerin üzerine çıkmadığı oldu mu? Bu kadar büyük bir değer, tüm farklı öğelerin daha düşük bir değere ayarlandığını veya hiç ayarlanmadığını varsayarak, bu öğeyi görsel olarak başka herhangi bir şeyin üzerine kolayca yerleştirmelidir. Bir web sayfası genellikle iki boyutlu bir alanda temsil edilir; ancak belirli CSS özellikleri uygulanarak derinliği iletmek için hayali bir z ekseni düzlemi eklenir. Bu düzlem ekrana diktir ve kullanıcı bu düzlemden öğelerin üst üste sırasını algılar. Kullanıcının yığılmış öğelere ilişkin algısı olan hayali z ekseninin ardındaki fikir, onu oluşturan CSS özelliklerinin yığınlama bağlamı dediğimiz şeyi oluşturmak için bir araya gelmesidir. Bir web sayfasında öğelerin nasıl "yığınlandığı", yığınlanma sırasını neyin kontrol ettiği ve gerektiğinde öğeleri "yığından çıkarma" konusunda pratik yaklaşımlar hakkında konuşacağız. Yığınlama Bağlamları Hakkında Web sayfanızı bir masa olarak hayal edin. HTML öğeleri ekledikçe, kağıt parçalarını birbiri ardına masanın üzerine koyarsınız. Yerleştirilen son kağıt parçası, en son eklenen HTML öğesine eşdeğerdir ve kendisinden önce yerleştirilen tüm diğer kağıtların üzerinde yer alır. Bu, iç içe geçmiş öğeler için bile normal belge akışıdır. Masanın kendisi, diğer tüm klasörleri içeren öğesi tarafından oluşturulan kök yığınlama bağlamını temsil eder. Artık belirli CSS özellikleri devreye giriyor. Konum (z-endeksi ile), opaklık, dönüştürme ve içerme gibi özellikler bir klasör gibi davranır. Bu klasör bir öğeyi ve onun tüm alt öğelerini alır, onları ana yığından çıkarır ve bunları ayrı bir alt yığın halinde gruplayarak yığınlama bağlamı dediğimiz şeyi oluşturur. Konumlandırılmış öğeler için bu, auto dışında bir z-endeksi değeri bildirdiğimizde gerçekleşir. Opaklık, dönüştürme ve filtre gibi özellikler için belirli değerler uygulandığında yığınlama bağlamı otomatik olarak oluşturulur.
Şunu anlamaya çalışın: Bir kağıt parçası (yani bir alt öğe) bir klasörün (yani üst öğenin yığın bağlamı) içine girdiğinde, o klasörden asla çıkamaz veya farklı bir klasördeki kağıtların arasına yerleştirilemez. Z-endeksi artık yalnızca kendi klasörüyle ilgilidir.
Aşağıdaki çizimde, Kağıt B artık Klasör B'nin yığınlama bağlamındadır ve yalnızca klasördeki diğer kağıtlarla birlikte sipariş edilebilir.
Masanızda iki klasör olduğunu hayal edin:
.folder-a { z-index: 1; } .folder-b { z-index: 2; }
İşaretlemeyi biraz güncelleyelim. A Klasörünün İçi özel bir sayfadır, z-endeksi: 9999. B Klasörünün İçi düz bir sayfadır, z-endeksi: 5.
.özel sayfa { z-index: 9999; } .plain-page { z-index: 5; }
Hangi sayfa üstte? Bu, B Klasöründeki .plain sayfasıdır. Tarayıcı alt kağıtları yok sayar ve önce iki klasörü yığar. B Klasörünü (z-endeksi: 2) görür ve onu A Klasörünün (z-endeksi: 1) üstüne yerleştirir çünkü ikinin birden büyük olduğunu biliyoruz. Bu arada, z-index: 9999 olarak ayarlanan .special-page sayfası, z-index'i mümkün olan en yüksek değere ayarlanmış olmasına rağmen yığının en altında yer alır. Yığınlama bağlamları da iç içe yerleştirilebilir (klasörlerin içindeki klasörler), bir "aile ağacı" oluşturulabilir. Aynı prensip geçerlidir: Bir çocuk asla ebeveynlerinin dosyasından kaçamaz. Artık yığınlama bağlamlarının katmanları gruplandıran ve yeniden sıralayan klasörler gibi nasıl davrandığını anladığınıza göre şu soruyu sormaya değer: neden dönüşüm ve opaklık gibi belirli özellikler yeni yığınlama bağlamları yaratıyor? Mesele şu ki: bu özellikler görünüşlerinden dolayı yığınlama bağlamları yaratmaz; bunu tarayıcının gizli çalışma şekli nedeniyle yapıyorlar. Dönüşüm, opaklık, filtre veya perspektif uyguladığınızda tarayıcıya şunu söylüyorsunuz: "Hey, bu öğe hareket edebilir, dönebilir veya soluklaşabilir; o yüzden hazır olun!"
Bu özellikleri kullandığınızda tarayıcı, oluşturmayı daha verimli bir şekilde yönetmek için yeni bir yığınlama bağlamı oluşturur. Bu, tarayıcının animasyonları, dönüşümleri ve görsel efektleri bağımsız olarak yönetmesine olanak tanır ve bu öğelerin sayfanın geri kalanıyla nasıl etkileşime girdiğini yeniden hesaplama ihtiyacını azaltır. Bunu, tarayıcının "Bu klasörü ayrı ayrı ele alacağım, böylece içindeki bir şey değiştiğinde tüm masayı yeniden karıştırmam gerekmeyecek" dediğini düşünün. Ama varbir yan etki. Tarayıcı bir öğeyi kendi katmanına kaldırdığında, yeni bir yığın bağlamı yaratarak içindeki her şeyi "düzleştirmesi" gerekir. Bu, ayrı ayrı ele almak için masadan bir klasör almak gibidir; bu klasörün içindeki her şey gruplandırılır ve tarayıcı artık neyin neyin üstünde olacağına karar verirken onu tek bir birim olarak ele alır. Dolayısıyla, dönüşüm ve opaklık özellikleri, öğelerin görsel olarak istiflenme şeklini etkilemiyor gibi görünse de, öyledir ve bu, performans optimizasyonu içindir. Diğer birçok CSS özelliği de benzer nedenlerle yığınlama bağlamları oluşturabilir. Daha derine inmek istiyorsanız MDN tam bir liste sağlar. Oldukça az sayıda var, bu da bilmeden yanlışlıkla bir yığınlama bağlamı oluşturmanın ne kadar kolay olduğunu gösteriyor. “Yığından Çıkarma” Sorunu Yığınlama sorunları birçok nedenden dolayı ortaya çıkabilir, ancak bazıları diğerlerinden daha yaygındır. Modal bileşenler klasik bir modeldir çünkü bileşenin diğer tüm öğelerin üzerindeki bir üst katmanda "açık" konuma getirilmesini, ardından "kapalı" olduğunda üst katmandan kaldırılmasını gerektirir. Hepimizin bir model açtığımız ve her ne sebeple olursa olsun görünmediği bir durumla karşılaştığımızdan oldukça eminim. Sorun düzgün açılmamasından değil, istifleme bağlamının alt katmanında görüş alanı dışında olmasından kaynaklanıyor. Bu sizi "nasıl oldu?" diye merak etmeye bırakıyor. ayarladığınızdan beri:
.yer paylaşımı { konum: sabit; /* yığınlama bağlamını oluşturur */ z-endeksi: 1; /* öğeyi diğer her şeyin üzerindeki bir katmana yerleştirir */ ek: 0; genişlik: %100; yükseklik: 100vh; taşma: gizli; arka plan rengi: #00000080; }
Bu doğru görünüyor, ancak modal tetikleyiciyi içeren ana öğe, aynı zamanda z-index: 1'e ayarlanmış başka bir ana öğe içindeki bir alt öğeyse, bu, modeli teknik olarak ana klasör tarafından gizlenen bir alt katmana yerleştirir. Bu spesifik senaryoya ve diğer birkaç yaygın yığınlama bağlamı tuzağına bakalım. Sanırım, yanlışlıkla yığınlama bağlamları oluşturmanın ne kadar kolay olduğunu değil, aynı zamanda bunların nasıl yanlış yönetileceğini de göreceksiniz. Ayrıca yönetilen duruma nasıl döneceğiniz duruma bağlıdır. Senaryo 1: Sıkışan Modal
Modalınızın düşük seviyeli bir katmanda sıkışıp kaldığını anında görebilir ve ebeveyni tanımlayabilirsiniz. Tarayıcı Uzantıları Akıllı geliştiriciler yardımcı olacak uzantılar geliştirdiler. Bu "CSS Yığınlama Bağlamı Denetleyicisi" Chrome uzantısı gibi araçlar, size bir yığınlama bağlamı oluşturan öğeler hakkında bilgi göstermek için DevTools'unuza ekstra bir z-index sekmesi ekler.
IDE Uzantıları Potansiyel yığınlama bağlamı sorunlarını doğrudan düzenleyicinizde vurgulayan VS Code için buna benzer bir uzantıyla geliştirme sırasında sorunları bile tespit edebilirsiniz.
İstiften Çıkarma ve Kontrolü Yeniden Kazanma Temel nedeni belirledikten sonra bir sonraki adım onunla ilgilenmektir. Bu sorunu çözmek için kullanabileceğiniz birkaç yaklaşım var ve bunları sırayla listeleyeceğim. Ancak herhangi bir seviyedeki herkesi seçebilirsiniz; kimse bir başkasını şikayet edemez, engelleyemez. HTML Yapısını Değiştirin Bu en uygun düzeltme olarak kabul edilir. Yığınlama bağlamı sorunuyla karşılaşmanız için, bazı öğeleri HTML'nizde komik konumlara yerleştirmiş olmanız gerekir. Sayfayı yeniden yapılandırmak DOM'u yeniden şekillendirmenize ve yığınlama bağlamı sorununu ortadan kaldırmanıza yardımcı olacaktır. Sorunlu öğeyi bulun ve onu HTML işaretlemesindeki yakalama öğesinden kaldırın. Örneğin ilk senaryo olan “The Trapped Modal”ı, .modal-container'ı başlıktan çıkarıp
elemanına tek başına yerleştirerek çözebiliriz.Bu içeriğin z-endeksi 2'dir ve yine de modeli kapsamaz.Başlık
Ana İçerik
“Kipi Aç” butonuna tıkladığınızda, model olması gerektiği gibi her şeyin önünde konumlandırılır. Bkz. Kalem Senaryosu 1: Sıkışan Modal (Çözüm) Shoyombo Gabriel Ayomide tarafından [çatallı]. AyarlayınCSS'de Ana Yığınlama Bağlamı Peki ya öğe, düzeni bozmadan taşıyamayacağınız bir öğeyse? Sorunu ele almak daha iyidir: ebeveyn bağlamı oluşturur. Bağlamı tetiklemekten sorumlu CSS özelliğini (veya özelliklerini) bulun ve kaldırın. Bir amacı varsa ve kaldırılamıyorsa, konteynerin tamamını kaldırmak için üst öğeye kardeş öğelerinden daha yüksek bir z-endeksi değeri verin. Daha yüksek bir z-endeksi değeriyle ana kapsayıcı en üste taşınır ve alt kapsayıcıları kullanıcıya daha yakın görünür. "Batık Açılır Menü" senaryosunda öğrendiklerimize dayanarak, açılır menüyü gezinme çubuğunun dışına taşıyamayız; hiçbir anlam ifade etmez. Ancak .navbar konteynerinin z-index değerini .content elemanının z-index değerinden büyük olacak şekilde artırabiliriz. .navbar { arka plan: #333; /* z-endeksi: 1; */ z-endeksi: 3; konum: göreceli; }
Bu değişiklikle birlikte .açılır menü artık içeriğin önünde sorunsuz bir şekilde görünüyor.
Bkz. Kalem Senaryosu 2: Shoyombo Gabriel Ayomide tarafından yazılan Batık Açılır Menü (Çözüm) [çatallı].
Bir Çerçeve Kullanıyorsanız Portalları Deneyin
React veya Vue gibi çerçevelerde Portal, bir bileşeni DOM'daki normal üst hiyerarşisinin dışında oluşturmanıza olanak tanıyan bir özelliktir. Portallar, bileşenleriniz için bir ışınlanma cihazı gibidir. Bir bileşenin HTML'sini belgenin herhangi bir yerinde (genellikle doğrudan document.body'de) oluşturmanıza olanak tanırken, onu aksesuarlar, durum ve olaylar açısından orijinal üst bileşenine mantıksal olarak bağlı tutar. İşlenen çıktı tam anlamıyla sorunlu ana kapsayıcının dışında göründüğünden, bu, yığın bağlam tuzaklarından kaçmak için mükemmeldir.
ReactDOM.createPortal(
Bu, üst öğede taşma: gizli veya daha düşük bir z-endeksi olsa bile açılır içeriğinizin üst öğenin arkasına gizlenmemesini sağlar. Daha önce incelediğimiz "Kırpılmış Araç İpucu" senaryosunda, araç ipucunu taşma: gizli klipten kurtarmak için bir Portal kullandım, onu belge gövdesine yerleştirdim ve kap içindeki tetikleyicinin üzerine konumlandırdım. Bkz. Kalem Senaryosu 3: Shoyombo Gabriel Ayomide tarafından yazılan Kırpılmış Araç İpucu (Çözüm) [çatallı]. Yan Etkileri Olmayan Yığınlama Bağlamıyla Tanışın Önceki bölümde açıklanan tüm yaklaşımlar, sorunlu yığınlama bağlamlarından öğeleri "yığından ayırmayı" amaçlamaktadır, ancak gerçekten bir yığınlama bağlamına ihtiyaç duyacağınız veya oluşturmak isteyeceğiniz bazı durumlar vardır. Yeni bir yığınlama bağlamı oluşturmak kolaydır ancak tüm yaklaşımların bir yan etkisi vardır. Yani, izolasyon kullanımı dışında: izolasyon. Bir öğeye uygulandığında, o öğenin alt öğelerinin yığın bağlamı, onun dışındaki öğelerden etkilenmek yerine, her bir alt öğeye göre ve bu bağlam içinde belirlenir. Klasik bir örnek, bu öğeye z-index: -1 gibi negatif bir değer atamaktır. Bir .card bileşeniniz olduğunu düşünün. .card metninin arkasında ancak kartın arka planının üstünde yer alan dekoratif bir şekil eklemek istiyorsunuz. Kartta bir yığın bağlamı olmadan z-index: -1, şekli kök yığın bağlamının (tüm sayfa) altına gönderir. Bu, kartın .card'ın beyaz arka planının arkasında kaybolmasını sağlar: Shoyombo Gabriel Ayomide tarafından yazılan Kalem Negatif z-endeksi (sorunu) [çatallanmış]'a bakın. Bunu çözmek için ebeveyn .card'da izolasyon: isulate ilan ederiz: Shoyombo Gabriel Ayomide tarafından yazılan Pen Negative z-indeksine (çözüm) [çatallı] bakın. Artık .card öğesinin kendisi bir yığınlama bağlamı haline gelir. Alt öğesi ( :before sözde öğesinde oluşturulan dekoratif şekil) z-index'e sahip olduğunda: -1, ebeveynin yığın bağlamının en altına gider. İstenildiği gibi metnin arkasına ve kartın arka planının üstüne mükemmel bir şekilde oturur. Sonuç Unutmayın: Z-index'iniz bir daha kontrolden çıkmış gibi göründüğünde, bu tuzağa düşmüş bir yığın bağlamıdır. Referanslar
Yığınlama bağlamı (MDN) Z-index ve yığınlama bağlamları (web.dev) “CSS'de Yalıtım Özelliğiyle Yeni Bir Yığınlama Bağlamı Nasıl Oluşturulur”, Natalie Pina "Ne oluyor, z-endeksi??", Josh Comeau
SmashingMag Hakkında Daha Fazla Okuma
“Büyük Projelerde CSS Z-Indexini Yönetmek”, Steven Frieson "Yapışkan Başlıklar ve Tam Yükseklikte Öğeler: Zor Bir Kombinasyon", Philip Braunen “Bileşen Tabanlı Bir Web Uygulamasında Z-Index'i Yönetmek”, Pavel Pomerantsev “Z-Index CSS Özelliği: Kapsamlı Bir Bakış”, Louis Lazaris