CSS z-index, konumlandırılmış öğelerin ve flex ile grid öğelerinin üst üste bindiklerinde hangisinin önde görüneceğini belirleyen özelliktir: Değeri büyük olan, küçük olanı örter. Ancak bu karşılaştırma yalnızca aynı stacking context (yığın bağlamı) içindeki öğeler arasında yapılır. z-index: 9999 verdiğiniz bir öğenin z-index: 1 olan başka bir öğenin arkasında kalmasının nedeni neredeyse her zaman budur.
Bu yazıda z-index değerlerinin anlamını, hiç z-index yazılmadığında tarayıcının öğeleri hangi sırayla çizdiğini, stacking context'i oluşturan durumları ve iç içe bağlamlarda sıralamayı "sürüm numarası" yöntemiyle nasıl okuyacağınızı MDN'nin konumlandırılmış düzen rehberlerine dayanarak anlatıyoruz. Konumlandırmanın kendisi için önce position yazısını okumanızı öneririz.
z-index neye uygulanır, hangi değerleri alır?

MDN'ye göre z-index, konumlandırılmış bir öğenin (position değeri static olmayan) ve onun alt öğelerinin ya da flex ve grid öğelerinin z sırasını belirler. position: static olan sıradan bir blok öğeye yazdığınız z-index hiçbir şey yapmaz. MDN'nin "Using z-index" rehberindeki örnekte de konumlandırılmamış bir öğeye verilen z-index değerinin etkisiz kaldığı gösterilir.
auto: Kutu yeni bir yerel stacking context oluşturmaz. Kutunun içinde bulunduğu bağlamdaki yığın düzeyi 0'dır.<integer>: Pozitif, sıfır ya da negatif bir tam sayıdır ve kutunun içinde bulunduğu bağlamdaki yığın düzeyini belirler. Kutu ayrıca yerel bir stacking context oluşturur; yani alt öğelerininz-indexdeğerleri bu öğenin dışındaki öğelerle karşılaştırılmaz.
İkinci maddedeki küçük ayrıntı bütün konunun özüdür: z-index değerini auto dışında bir şey yapmak (konumlandırılmış ya da flex/grid öğesinde) yeni bir bağlam açar ve alt öğeleri o bağlama hapseder. z-index: 0 ile z-index: auto bu yüzden aynı şey değildir: İkisinde de yığın düzeyi 0'dır, ama yalnızca 0 yeni bir bağlam oluşturur.
MDN, z eksenini numaralı katmanlardan oluşan bir yığın olarak düşünmeyi önerir. Katmanlar sayı sırasıyla çizilir; büyük sayılar küçüklerin üstünde, yani izleyiciye daha yakın durur:
| Katman | Açıklama |
|---|---|
| En alt katman | İzleyiciden en uzak |
| Katman -X | Negatif z-index değerleri |
| Katman 0 | Varsayılan çizim katmanı |
| Katman X | Pozitif z-index değerleri |
| En üst katman (top layer) | İzleyiciye en yakın |
z-index belirtilmemiş öğeler varsayılan katman olan Katman 0'da çizilir. Aynı z-index değerini paylaşan, yani aynı katmana düşen öğeler arasında ise z-index olmadan geçerli olan sıralama kuralları uygulanır.
z-index olmadan sıralama
Hiçbir öğede z-index yoksa MDN'ye göre öğeler alttan üste şu sırayla çizilir:
- Kök öğenin arka planı ve kenarlıkları.
- Konumlandırılmamış alt öğeler, HTML'deki görünme sırasıyla.
- Kayan (float) öğeler.
- Konumlandırılmış alt öğeler, HTML'deki görünme sırasıyla.
Bu listeden çıkan sonuç şudur: Konumlandırılmış bir öğe, kaynak kodda kendisinden sonra gelen konumlandırılmamış bir öğenin bile üstünde çizilir. MDN'nin örneğinde dört konumlandırılmış <div> ve bir static <div> vardır; static olan HTML'de en sonda gelse de diğer dördünün altında çizilir. Konumlandırılmış öğeler kendi aralarında ise kaynak sırasına göre dizilir: sonra gelen üstte görünür.
Kayan öğelerin yeri konumlandırılmamış öğeler ile konumlandırılmış öğeler arasındadır. MDN bu bağlamda ilginç bir durumu da not eder: Konumlandırılmamış bir öğeye opacity değeri verildiğinde, o öğenin arka planı ve kenarlığı kayan ve konumlandırılmış blokların üstüne çıkabilir. Bunun nedeni opacity değerinin yeni bir stacking context oluşturmasıdır. Ayrıca flex kapsayıcılarında order özelliği çizim sırasını HTML sırasından farklı hale getirdiğinde, yığın sırası da aynı şekilde etkilenir.
Stacking context nedir?
Stacking context, öğelerin kullanıcıya bakan hayali bir z ekseni boyunca nasıl üst üste dizileceğini belirleyen üç boyutlu bir kavramdır. MDN üç temel özelliğini vurgular. Birincisi, bir bağlamın içindeki öğeler dışındaki öğelerden bağımsız olarak sıralanır. İkincisi, bir öğenin içeriği kendi bağlamında sıralandıktan sonra öğenin tamamı, üst bağlamda tek bir birim olarak ele alınır. Üçüncüsü, bağlamlar iç içe geçebilir ve bir hiyerarşi oluşturur; bu hiyerarşi HTML ağacının bir alt kümesidir, çünkü yalnızca bazı öğeler bağlam oluşturur. Bağlam oluşturmayan öğeler, ebeveyn bağlam tarafından "özümsenir".
Bu tanımın pratik anlamı şudur: Bir öğenin z sırası, kendi z-index değerinden önce, atalarından hangisinin bağlam oluşturduğuna ve o atanın üst bağlamdaki sırasına bağlıdır. Bir bağlamın içindeki hiçbir öğe, ne kadar yüksek z-index alırsa alsın, o bağlamın dışındaki ve bağlamdan daha üstte çizilen bir öğenin önüne geçemez.
Stacking context oluşturan durumlar

MDN'nin listesine göre aşağıdaki durumlardan herhangi birindeki öğe yeni bir stacking context oluşturur. Listenin uzun olması, "z-index çalışmıyor" sorununun neden bu kadar sık yaşandığını açıklar: Bağlamların çoğu z-index ile değil, görsel efektlerle açılır.
- Belgenin kök öğesi (
<html>). positiondeğeriabsoluteya darelativeolupz-indexdeğeriautoolmayan öğe.positiondeğerifixedya dastickyolan öğe (z-index gerekmez).z-indexdeğeriautoolmayan flex öğesi ya da grid öğesi.container-typedeğerisizeya dainline-sizeolan öğe.opacitydeğeri 1'den küçük olan öğe.mix-blend-modedeğerinormalolmayan öğe.transform,scale,rotate,translate,filter,backdrop-filter,perspective,clip-path,mask,mask-imageya damask-borderdeğerinoneolmayan öğe.isolationdeğeriisolateolan öğe.- Bağlam oluşturan bir özelliği belirten
will-changedeğerine sahip öğe. containdeğerilayoutya dapaintolan, ya da bunları içerenstrictveyacontentdeğerine sahip öğe.- En üst katmana (top layer) yerleştirilen öğe ve onun
::backdropsözde öğesi; örneğin tam ekran ve popover öğeleri. opacitygibi bağlam oluşturan bir özelliği@keyframesile canlandırılmış veanimation-fill-mode: forwardsverilmiş öğe.
Bu listedeki transform, filter ve opacity gibi özelliklerin ayrıntısı transform yazısında, filter ve backdrop-filter yazısında ve animation yazısında anlatılıyor; container-type ise container queries yazısının konusu.
İç içe bağlamları "sürüm numarası" ile okumak
MDN, iç içe bağlamlardaki çizim sırasını bulmak için her z-index değerini bir sürüm numarası gibi düşünmeyi önerir: Ebeveyn bağlamın değeri ana sürüm, alt öğenin değeri ara sürümdür. Rehberdeki örnekte kök bağlamda üç kardeş <article> vardır ve üçüncüsü üç <section> içerir. Hepsi opacity: 0.85 ve position: relative (ikisi absolute) değerine sahip olduğu için her biri bağlam oluşturur.
section,
article {
opacity: 0.85;
position: relative;
}
#container1 { z-index: 5; } /* ARTICLE #1 */
#container2 { z-index: 2; } /* ARTICLE #2 */
#container3 { /* ARTICLE #3 */
z-index: 4;
position: absolute;
}
#container4 { z-index: 6; } /* SECTION #4, ARTICLE #3 içinde */
#container5 { z-index: 1; } /* SECTION #5, ARTICLE #3 içinde */
#container6 { /* SECTION #6, ARTICLE #3 içinde */
z-index: 3;
position: absolute;
}Sürüm numaralarıyla yazınca sıralama netleşir. Alttan üste çizim sırası şöyledir:
| Öğe | Kendi z-index | Sürüm numarası |
|---|---|---|
| ARTICLE #2 | 2 | 2-0 |
| ARTICLE #3 | 4 | 4-0 |
| SECTION #5 | 1 | 4-1 |
| SECTION #6 | 3 | 4-3 |
| SECTION #4 | 6 | 4-6 |
| ARTICLE #1 | 5 | 5-0 |
Tablodan iki şaşırtıcı sonuç çıkar. SECTION #4 kendi değeri 6 olduğu halde z-index değeri 5 olan ARTICLE #1'in altında kalır, çünkü 4-6 sürümü 5-0 sürümünden küçüktür; SECTION #4'ün 6 değeri yalnızca ARTICLE #3'ün içinde anlamlıdır. Öte yandan SECTION #5 kendi değeri 1 olduğu halde z-index değeri 2 olan ARTICLE #2'nin üstünde görünür, çünkü 4-1 sürümü 2-0 sürümünden büyüktür.
MDN'nin "Understanding z-index" rehberindeki daha küçük örnek de aynı mantığı gösterir: z-index: 2 olan bir <section> içinde z-index: -9 değerli bir öğe, section'ın kardeşi olan ve z-index: 0 değerli bir öğenin üstünde görünür. -9, 0'dan küçüktür ama karşılaştırma section (2) ile kardeşi (0) arasında yapılır.
isolation: bilinçli olarak bağlam açmak
Bazen yeni bir stacking context'e ihtiyaç duyarsınız ama bunu z-index ya da görsel bir efektle yapmak istemezsiniz. isolation özelliği tam bu iş içindir. auto değerinde bağlam yalnızca başka bir özellik gerektirdiğinde oluşur; isolate değerinde ise yeni bir bağlam oluşturulması zorunlu hale gelir. MDN bu özelliğin özellikle mix-blend-mode ve z-index ile birlikte kullanıldığında yararlı olduğunu belirtir.
.bilesen {
isolation: isolate;
/* yeni stacking context: içerideki z-index değerleri
dışarıdaki öğelerle karşılaştırılmaz */
}
.bilesen .arka-dekor {
position: absolute;
z-index: -1;
/* bileşenin kendi bağlamı içinde geride kalır */
}Uygulamalı mini örnek: başlığın arkasında kalan menü
Sık görülen bir senaryo: Sayfa başlığı position: sticky ve z-index: 10 değerine sahip. Ana içerikteki bir açılır menüye position: absolute ve z-index: 1000 veriyorsunuz, ama menü yine başlığın altında kalıyor.
header {
position: sticky;
top: 0;
z-index: 10;
}
main {
position: relative;
z-index: 1;
/* main kendi bağlamını oluşturur, kök bağlamdaki değeri 1 */
}
main .menu {
position: absolute;
z-index: 1000;
/* sürüm numarası: 1-1000; header ise 10-0
1-1000 < 10-0, menü başlığın altında kalır */
}Menünün 1000 değeri yalnızca main bağlamının içinde geçerlidir; kök bağlamda karşılaştırılan değerler main için 1, header için 10'dur. Çözüm için üç yol vardır: main üzerindeki z-index değerini kaldırmak (böylece main bağlam oluşturmaz ve menü kök bağlamda 1000 ile yarışır), main değerini 10'dan büyük yapmak ya da menüyü HTML'de main dışına taşımak. Aynı sorun main üzerinde z-index yerine opacity, transform ya da filter olduğunda da yaşanır; bu durumda önce bağlamı hangi özelliğin açtığını bulmanız gerekir.
Bu senaryodaki düşünme biçimini her durumda kullanabilirsiniz. Önce üst üste binen iki öğenin ortak bağlamını bulun: İkisinin de atası olan ve bağlam oluşturan en yakın öğe. Sonra her iki öğeden bu ortak bağlama doğru çıkarak, ortak bağlamın doğrudan içinde yarışan temsilcileri belirleyin. Karşılaştırma yalnızca bu iki temsilcinin z-index değerleri (eşitse kaynak sırası) üzerinden yapılır; alttaki değerlerin hiçbiri bu sonucu değiştiremez.
Sık yapılan hatalar

- Konumlandırılmamış öğeye
z-indexvermek: Öğe flex ya da grid öğesi değilse etkisi olmaz. - Sorunu daha büyük sayılarla çözmeye çalışmak: Farklı bağlamlardaki öğeler için sayı büyütmek işe yaramaz; bağlamı oluşturan atayı bulun.
opacity,transformya dafilteretkisini unutmak: Bu özelliklerz-indexolmadan da bağlam oluşturur.z-index: 0ileautodeğerini aynı sanmak: Yığın düzeyi ikisinde de 0'dır, ama yalnızca 0 yeni bağlam açar.fixedvestickyöğelerin her zaman bağlam oluşturduğunu bilmemek: İçlerindeki öğeler dışarıyla doğrudan yarışamaz.
Sık Sorulan Sorular
z-index: 9999 neden çalışmıyor?
Öğe büyük ihtimalle ataları tarafından oluşturulan bir stacking context'in içindedir ve karşılaştırma o atanın üst bağlamdaki değeri üzerinden yapılır. Ya da öğe konumlandırılmamıştır; o durumda z-index hiç uygulanmaz.
Negatif z-index ne işe yarar?
Öğeyi içinde bulunduğu bağlamın varsayılan katmanının (Katman 0) arkasına yerleştirir. MDN'nin katman tablosunda negatif değerler varsayılan katmanın altında yer alır. Öğenin hangi öğelerin arkasına geçeceği, yine hangi bağlamda olduğuna bağlıdır.
Popover ve tam ekran öğeleri neden her şeyin üstünde?
Bu öğeler en üst katmana (top layer) yerleştirilir. MDN'nin katman tablosunda en üst katman izleyiciye en yakın katmandır ve pozitif z-index değerli katmanların da üstünde yer alır. En üst katmana yerleştirilen öğe ve onun ::backdrop sözde öğesi ayrıca kendi stacking context'ini oluşturur. Bu yüzden sayfadaki bir öğeye ne kadar büyük z-index verirseniz verin, en üst katmandaki bir öğenin önüne geçiremezsiniz.
Flex öğelerinde z-index çalışır mı?
Evet. MDN'ye göre z-index flex ve grid öğelerinde position değeri static olsa da çalışır ve auto dışındaki bir değer yeni bir stacking context oluşturur.
Stacking context ile blok biçimlendirme bağlamı aynı şey mi?
Hayır. Stacking context z eksenindeki çizim sırasıyla, blok biçimlendirme bağlamı ise kutuların yerleşimi, kayan öğeler ve margin çökmesiyle ilgilidir. Bazı özellikler ikisini birden oluşturabilir, ama kavramlar ayrıdır. BFC için display yazısına bakabilirsiniz.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: CSS öğrenme rehberi · position değerleri · transform · filter ve backdrop-filter · Flexbox rehberi · CSS sık hatalar