Z-index to właściwość w CSS, która kontroluje układ warstwowy elementów na stronie internetowej. Mówiąc prościej – decyduje, który element będzie wyświetlany na wierzchu, a który pod spodem, gdy dwa lub więcej elementów nachodzi na siebie. Właściwość z-index przyjmuje wartość liczbową (całkowitą), gdzie element z wyższą wartością będzie ułożony ponad elementem z niższą wartością (np. element o z-index: 10 przykryje element z z-index: 5). z-index działa tylko dla elementów, które nie są statyczne (muszą mieć position inną niż static) – elementy statyczne nie tworzą stosu warstw i nie reagują na tę właściwość.
Jak działa z-index?
Właściwość z-index wpływa na tzw. stos układania elementów (ang. stacking order) w dokumencie HTML. Każdy element na stronie, który może nakładać się na inny, jest częścią pewnego stosu warstw. Domyślnie, gdy elementy nie mają nadanych wartości z-index, ich kolejność na ekranie wynika z kolejności w kodzie – element umieszczony później w HTML przykryje poprzedni, jeśli zachodzi na ten sam obszar. Wprowadzając wartości z-index, możemy jednak tę kolejność zmieniać niezależnie od ułożenia w kodzie.
Kluczowe jest zrozumienie pojęcia kontekstu warstw (stacking context). Jest to lokalna przestrzeń układania elementów. Pewne elementy – na przykład te z pozycjonowaniem innym niż static – tworzą własny kontekst warstw. Działa to w ten sposób, że dzieci takiego elementu układają się względem siebie (według swoich z-index) wewnątrz tego kontekstu, ale cały ten zagnieżdżony kontekst ma swoją pozycję w stosie warstw dokumentu. Na przykład, jeżeli element z position: relative i z-index: 1 zawiera w sobie dziecko z z-index: 999, to i tak ten element podrzędny nie wysunie się ponad inne elementy spoza kontenera, ponieważ ogranicza go kontekst warstw utworzony przez element nadrzędny. Oznacza to, że nawet jeśli element podrzędny ma bardzo wysoki z-index, nie „wydostanie się” ponad element nadrzędny, który stanowi granicę kontekstu. Dopiero porównanie z-index elementów znajdujących się w tym samym kontekście warstw (np. rodzeństwo ze wspólnym rodzicem) pozwala ustalić, który będzie na wierzchu. Innymi słowy – z-index działa tylko w obrębie bieżącego kontekstu warstw.
Typowe zastosowania właściwości z-index
Właściwość z-index jest szczególnie przydatna w sytuacjach, gdy elementy strony nakładają się na siebie i chcemy kontrolować, który z nich ma być widoczny na wierzchu. Oto kilka typowych scenariuszy wykorzystania z-index:
- Menu rozwijane i nawigacje – Rozwijane menu (dropdown) powinno pojawić się ponad innymi elementami strony (tekstem, obrazkami) tak, aby jego opcje były dostępne. Ustawienie wysokiego z-index dla panelu menu zapewnia, że żaden element poniżej go nie przykryje.
- Okna modalne, popupy – Wyskakujące okienka dialogowe (modal) wyświetlane na środku ekranu zazwyczaj blokują interakcję z resztą strony. Dzięki wysokiemu z-index takie okno pojawia się na samym wierzchu, a często dodatkowo półprzezroczysty overlay (również z wysokim z-index) przykrywa resztę zawartości strony.
- Sticky header i footer – Gdy korzystamy z pozycji fixed lub sticky dla nagłówka (header) lub stopki (footer), zwykle nadajemy im wyższy z-index, by podczas przewijania strony zawsze pozostawały na wierzchu i nie były zasłaniane przez inne sekcje przewijanej treści.
- Elementy z efektem parallax – W designie typu parallax różne warstwy zawartości przesuwają się w różnym tempie, tworząc efekt głębi. z-index pozwala rozmieścić te warstwy (np. tło, przedni plan) w odpowiedniej kolejności – np. chmury na tle nieba mają niższy z-index, a obiekty na pierwszym planie wyższy, dzięki czemu nachodzą na tło.
- Nakładające się obrazy i galerie – W zaawansowanych układach graficznych lub galeriach zdjęć elementy mogą celowo nachodzić na siebie (np. stos zdjęć). Poprzez manipulację z-index możemy kontrolować kolejność widocznych fragmentów – np. ustalić, które zdjęcie jest „na wierzchu” stosu.
Częste problemy z z-index i jak ich uniknąć
Podczas pracy z z-index można natrafić na typowe trudności, przez które element mimo nadania wysokiej wartości wciąż nie pojawia się na wierzchu. Oto najczęstsze problemy i sposoby ich rozwiązania:
- Brak ustawionego pozycjonowania – Jeśli z-index zdaje się nie działać, pierwszą rzeczą do sprawdzenia jest deklaracja position elementu. Elementy o pozycji statycznej (position: static;) ignorują z-index. Rozwiązanie: nadać elementowi pozycję relative (lub absolute/fixed/sticky) – to stworzy nowy kontekst i umożliwi działanie z-index.
- Niewłaściwy kontekst warstw – Czasem element z wysokim z-index wciąż jest zasłaniany, bo znajduje się w niższym kontekście warstw. Na przykład kontener o niskim z-index ogranicza swoje dzieci. Rozwiązanie: sprawdzić hierarchię elementów i wartości z-index dla wszystkich przodków. Być może trzeba zwiększyć z-index elementu nadrzędnego lub przenieść element na inny poziom DOM, gdzie nie ogranicza go rodzic.
- Konflikt z innymi właściwościami – Niektóre właściwości CSS (np. transform, filter, opacity) tworzą nowy kontekst warstw nawet bez position. Może to prowadzić do niespodziewanych zachowań – element z opacity: 0.5 staje się nowym kontekstem i jego dzieci nie wyjdą poza ten półprzezroczysty element. Rozwiązanie: unikać niepotrzebnego stosowania tych właściwości lub w razie potrzeby podnieść z-index kontenera, albo zmienić strukturę HTML, by wyeliminować niechciany kontekst.
- Zbyt duże wartości i chaos warstw – Nadawanie arbitralnie wysokich wartości z-index (np. 99999) bywa kuszące, ale na dłuższą metę prowadzi do bałaganu. Inni deweloperzy mogą dać równie wysoką lub wyższą wartość innemu elementowi i problem powróci. Rozwiązanie: planować warstwy z wyprzedzeniem. Można ustalić pewien zakres z-index dla różnych typów elementów (np. nawigacja 1000-1100, modal 2000 itp.), aby trzymać porządek. Dzięki temu unikniemy wojen na coraz wyższe liczby i zachowamy czytelność.
Najlepsze praktyki przy korzystaniu z z-index
Aby uniknąć problemów i utrzymać kod CSS czytelnym, warto przestrzegać kilku zasad podczas zarządzania warstwami za pomocą z-index:
- Planowanie warstw z wyprzedzeniem – Zastanów się nad układem warstw już na etapie projektowania interfejsu. Określ, jakie elementy powinny być zawsze na wierzchu (np. nawigacja, modalne okna, wysuwane panele) i przypisz im sensowne wartości z-index z odpowiednim zapasem. Unikaj nadmiernego windowania wartości – lepiej trzymać się ustalonych zakresów niż sięgać od razu po ekstremalne liczby.
- Minimalizowanie nowych kontekstów warstw – Twórz nowe konteksty warstw tylko wtedy, gdy to konieczne. Na przykład nie dodawaj zbędnie position: relative do elementów, które go nie potrzebują, bo każdy taki element stanowi potencjalną barierę dla z-index potomków. Utrzymuj strukturę DOM możliwie płaską w miejscach, gdzie ma dochodzić do nakładania elementów – łatwiej wtedy kontrolować kolejność warstw.
- Czytelność i dokumentowanie – Gdy ustawiasz konkretne wartości z-index (zwłaszcza te mniej oczywiste), warto dodać komentarz w kodzie CSS wyjaśniający, czemu dany element ma akurat taką wartość. Ułatwi to innym osobom (lub Tobie samemu po czasie) zrozumienie logiki warstw. Dobrą praktyką jest też grupowanie definicji warstw w jednym miejscu arkusza stylów (np. sekcja z ustawieniami z-index dla kluczowych elementów), co pozwala szybko ogarnąć cały obraz hierarchii.
- Testowanie nakładania elementów – Po wprowadzeniu zmian w wartościach z-index sprawdź dokładnie, czy efekt jest zgodny z oczekiwaniami. Przetestuj stronę w różnych przeglądarkach oraz przy różnych rozdzielczościach/układach (tryb responsywny), by upewnić się, że żaden element nie „przebija się” lub nie znika, kiedy nie powinien. Wykorzystuj narzędzia developerskie – w inspektorze można podejrzeć, jakie konteksty warstw zostały utworzone i jakie z-index mają poszczególne elementy, co pomaga w debugowaniu.