Z-index va Stacking Context

~15 daq · CSS · Pozitsiya va Responsive

Muammodan boshlaylik

Modal oyna ochdingiz — lekin sahifadagi sticky header uning ustida ko'rinyapti. Modalga z-index: 100 berasiz — hech narsa o'zgarmadi. z-index: 9999 — yana header ustida. Alamdan z-index: 2147483647 (maksimal son) — baribir header ustida.

Bu — CSS dagi eng ko'p asabga tegadigan muammolardan biri. Sabab z-index ning qiymatida emas, stacking context degan tushunchada. Uni tushunsangiz, "z-index urushlari" tugaydi.


z-index — uchinchi o'lchov

Elementlar bir-birining ustiga tushganda (23-dars: absolute, fixed, manfiy margin, Grid ustma-ust joylash) qaysi biri ustda ko'rinishini z-index belgilaydi — ekrandan foydalanuvchiga qarab yo'nalgan "Z o'qi".

.a { position: relative; z-index: 1; }
.b { position: relative; z-index: 2; }   /* .a ning ustida */
  • Katta qiymat — ustda
  • Manfiy qiymat mumkin: z-index: -1 — orqaga
  • Qiymat teng yoki yo'q bo'lsa — HTML tartibi: keyingi element ustda

[!WARNING] z-index faqat pozitsiyalangan elementlarda (position — static emas), shuningdek flex va grid elementlarda ishlaydi. Oddiy static elementga z-index: 999 berish hech narsa qilmaydi — "z-index ishlamayapti" ning birinchi sababi.


Stacking context — "qatlamlar guruhi"

Endi asosiy qism. Stacking context — o'z ichida z-index lar alohida hisoblanadigan guruh. Uni rasmdagi qatlamlar papkasi deb tasavvur qiling (Photoshop yoki Figma dagi kabi):

Sahifa (ildiz kontekst)
├── header       z-index: 10   ← o'z kontekstini yaratadi
│     └── menyu     z-index: 999
└── main         z-index: 1    ← o'z kontekstini yaratadi
      └── modal     z-index: 9999

Modal ning z-index: 9999 i faqat main ichida ma'noga ega. Sahifa darajasida main (1) va header (10) solishtiriladi — header yutadi. Modal main bilan birga pastda qoladi, 9999 qanchalik katta bo'lmasin.

Bu darsning boshidagi muammo: modal z-index: 1 li konteyner ichida joylashgan edi.

Qoida: bola o'z ota kontekstidan yuqoriga chiqa olmaydi. Papka ichidagi qatlam, papkaning o'zi pastda bo'lsa, boshqa papkalarning ustiga chiqmaydi.


Stacking context ni nima yaratadi

Bu ro'yxat muhim — ko'p kutilmagan muammolar shundan:

Xususiyat Kontekst yaratadi
position: relative/absolute + z-index (auto emas) ✅
position: fixed yoki sticky ✅ (z-index siz ham)
Flex yoki grid element + z-index ✅
opacity 1 dan kichik ✅
transform (har qanday, hatto translateZ(0)) ✅
filter, backdrop-filter ✅
isolation: isolate ✅ — maxsus shu maqsad uchun
will-change: transform/opacity ✅
mix-blend-mode ✅

Ya'ni hech qanday z-index yozmasdan, faqat opacity: 0.99 yoki animatsiya uchun transform qo'shsangiz ham — yangi kontekst paydo bo'ladi va uning ichidagi elementlar endi undan yuqoriga chiqa olmaydi.


Muammolarni hal qilish

1. Elementni kontekstdan chiqarish

Modal, toast, dropdown — sahifaning hamma narsasidan ustda bo'lishi kerak bo'lgan elementlarni body ning bevosita bolasi qiling (yoki sahifa oxiridagi alohida konteynerga):

<body>
  <header>...</header>
  <main>...</main>
  <div class="modal">...</div>    <!-- main ichida emas -->
</body>

React va Vue dagi "portal" (Teleport) aynan shu ishni bajaradi: komponent kodi ichma-ich bo'lsa ham, DOM da modal body oxiriga joylashadi.

2. Native dialog — top layer

<dialog id="tasdiq">
  <p>O'chirishni tasdiqlaysizmi?</p>
  <button>Ha</button>
</dialog>
document.getElementById('tasdiq').showModal();

<dialog> ning showModal() yoki popover atributi bilan ochilgan elementlar maxsus top layer ga tushadi — ular har qanday z-index va kontekstdan ustda, HTML da qayerda bo'lishidan qat'i nazar. Zamonaviy modal va popoverlar uchun eng ishonchli yo'l.

3. isolation: isolate

Komponentning ichki z-index lari tashqariga "sizib chiqmasligi" uchun:

.card {
  isolation: isolate;     /* yangi kontekst — boshqa hech narsa o'zgarmaydi */
}

.card .bg   { z-index: -1; }   /* faqat kartochka ichida orqada */
.card .text { z-index: 1; }

Busiz z-index: -1 element butun sahifaning orqasiga tushib, ko'rinmay qolishi mumkin.


Tartibli z-index tizimi

Tasodifiy 999, 9999, 99999 o'rniga — loyiha uchun bitta shkala, o'zgaruvchilarda (6-dars):

:root {
  --z-base: 1;
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-header: 300;
  --z-overlay: 400;
  --z-modal: 500;
  --z-toast: 600;
}

.header   { z-index: var(--z-header); }
.dropdown { z-index: var(--z-dropdown); }
.modal    { z-index: var(--z-modal); }

Har bir qatlamning o'z joyi bor, yangi narsa qo'shilganda "qaysi raqam" deb o'ylash shart emas. Va bu raqamlar faqat bir xil kontekstda turgan elementlar uchun ishlashini yodda tuting.


Tashxis: "z-index ishlamayapti"

  1. Element pozitsiyalanganmi (yoki flex/grid elementmi)? Aks holda z-index e'tiborsiz
  2. Raqib element bilan ular bitta kontekstdami? DevTools da ajdodlarni yuqoriga qarab tekshiring: z-index, opacity, transform, filter qayerda bor?
  3. Ota kontekstning z-index i raqibnikidan kichik bo'lsa — bolaning z-index ini oshirish foydasiz; otani o'zgartiring yoki elementni boshqa joyga ko'chiring
  4. Chrome DevTools → Layers paneli (More tools → Layers) kontekstlarni 3D da ko'rsatadi

Nima uchun shunday?

Nima uchun z-index global emas — har bir element shunchaki o'z raqami bo'yicha solishtirilsa sodda bo'lmasmidi?

Chunki kontekstlar komponentlarni himoya qiladi. Kutubxonadan olingan kartochka komponenti ichida z-index: 2 li bezak bor. Agar z-index global bo'lsa, bu bezak sahifadagi sizning z-index: 1 li header ingizning ustiga chiqib qolardi — komponent muallifi sizning sahifangizni bilmagan holda. Kontekst bilan esa komponentning ichki qatlamlari faqat o'z ichida solishtiriladi: kartochka bir butun sifatida sahifaga "bir qatlam" bo'lib qo'shiladi. Bu inkapsulyatsiya — dasturlashdagi funksiya ichidagi lokal o'zgaruvchilar kabi. Muammo faqat siz buni bilmaganda paydo bo'ladi — va endi siz bilasiz.


Xulosa

Eslab qoling:

  • z-index — katta qiymat ustda; teng bo'lsa — HTML da keyingisi
  • Faqat pozitsiyalangan, flex yoki grid elementlarda ishlaydi
  • Stacking context — z-index lar ichida alohida hisoblanadigan guruh; bola otasidan yuqoriga chiqmaydi
  • Kontekst yaratadi: z-index + position, fixed/sticky, opacity < 1, transform, filter, isolation: isolate
  • Modal va toast — body ning bevosita bolasi, yoki <dialog>/popover (top layer)
  • isolation: isolate — komponentning ichki qatlamlarini o'rab olish
  • Z-index shkalasi — CSS o'zgaruvchilarida

Keyingi dars

25-dars: Responsive Design — Mobile First kontseptsiyasi