Kurs HTML

7.5. Kolejność nakładania (z-index)

Strona główna > Kurs CSS > Rozdział 7: Wyświetlanie i Pozycjonowanie > Kolejność nakładania (z-index)

Wprowadzenie: Kto jest na wierzchu?

Gdy elementy są pozycjonowane (za pomocą position: relative, absolute, fixed lub sticky), mogą one na siebie nachodzić. Właściwość z-index w CSS pozwala kontrolować **kolejność nakładania się (stacking order)** tych pozycjonowanych elementów wzdłuż osi Z (prostopadłej do ekranu).

Element z wyższą wartością z-index pojawi się **na wierzchu** elementu z niższą wartością z-index.

Ważne: Właściwość z-index działa **tylko na elementach pozycjonowanych** (tych, których position jest inne niż static).

Jak działa z-index?

  • Wartości: z-index przyjmuje wartości całkowite (dodatnie, ujemne lub zero) lub słowo kluczowe auto (domyślne).
    • auto: Element dziedziczy kolejność stosu z kontekstu nadrzędnego, zazwyczaj renderowany jest w kolejności pojawiania się w HTML.
    • Liczby całkowite: Wyższa liczba oznacza wyższą pozycję na stosie (bliżej użytkownika).
  • Konteksty Stosu (Stacking Contexts): z-index działa tylko w obrębie tego samego **kontekstu stosu**. Elementy w różnych kontekstach stosu są porównywane na podstawie kolejności ich kontekstów, a nie bezpośrednio ich wartości z-index.
<div class="box box1">Box 1 (z-index: 1)</div>
<div class="box box2">Box 2 (z-index: 2)</div>
<div class="box box3">Box 3 (z-index: auto/0)</div>
.box {
  position: absolute; /* Muszą być pozycjonowane */
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

.box1 {
  background-color: red;
  top: 10px; left: 10px;
  z-index: 1;
}

.box2 {
  background-color: green;
  top: 30px; left: 30px;
  z-index: 2; /* Wyższy z-index, będzie na wierzchu box1 */
}

.box3 {
  background-color: blue;
  top: 50px; left: 50px;
  /* z-index: auto; (domyślnie) lub z-index: 0; */
  /* Będzie pod box1 i box2 */
}

W powyższym przykładzie, zielone pudełko (z-index: 2) pojawi się na wierzchu czerwonego (z-index: 1), a oba pojawią się na wierzchu niebieskiego (z-index: auto lub 0).

Konteksty Stosu (Stacking Contexts)

Kontekst stosu to grupa elementów, które współdzielą tę samą przestrzeń na osi Z i są porównywane ze sobą pod względem z-index. Elementy zagnieżdżone w jednym kontekście stosu nie mogą pojawić się "pomiędzy" elementami w innym kontekście stosu.

Nowy kontekst stosu jest tworzony przez element, który spełnia **jedno** z poniższych kryteriów:

  • Element root (<html>).
  • Element z position ustawionym na absolute lub relative i z-index innym niż auto.
  • Element z position ustawionym na fixed lub sticky.
  • Element będący dzieckiem kontenera Flexbox z z-index innym niż auto.
  • Element będący dzieckiem kontenera Grid z z-index innym niż auto.
  • Element z opacity mniejszym niż 1.
  • Element z transform, filter, perspective, clip-path, mask innymi niż wartość domyślna.
  • Element z isolation: isolate;.
  • Element z will-change określającym właściwość tworzącą kontekst stosu.
  • ...i kilka innych, mniej powszechnych przypadków.

Kluczowa zasada: Elementy wewnątrz danego kontekstu stosu są układane zgodnie z ich z-index. Następnie cały ten kontekst stosu jest traktowany jako pojedyncza jednostka przy porównywaniu z innymi kontekstami stosu lub elementami w kontekście nadrzędnym.

<div class="parent1"> 
  Parent 1 (z-index: 1)
  <div class="child1">Child 1 (z-index: 100)</div>
</div>
<div class="parent2"> 
  Parent 2 (z-index: 2)
  <div class="child2">Child 2 (z-index: 50)</div>
</div>
div {
  position: relative; /* Aby z-index zadziałał i stworzył kontekst */
  padding: 20px;
  margin: 10px;
  border: 1px solid black;
}

.parent1 { z-index: 1; background: lightblue; }
.child1  { z-index: 100; background: cyan; position: absolute; top: 50px; left: 50px; }

.parent2 { z-index: 2; background: lightcoral; }
.child2  { z-index: 50; background: pink; position: absolute; top: 50px; left: 50px; }

/* Mimo że .child1 ma z-index: 100, a .child2 ma z-index: 50, */
/* cały .parent2 (z-index: 2) pojawi się NA WIERZCHU całego .parent1 (z-index: 1). */
/* Dlatego .child2 będzie na wierzchu .child1. */

Zrozumienie kontekstów stosu jest kluczowe przy pracy ze złożonymi layoutami i nakładającymi się elementami.

Kolejność renderowania w ramach tego samego kontekstu stosu

W obrębie jednego kontekstu stosu, elementy są renderowane (rysowane) w następującej kolejności (od spodu do wierzchu):

  1. Tło i obramowanie elementu tworzącego kontekst stosu.
  2. Potomne konteksty stosu z ujemnym z-index (najpierw te z niższym z-index).
  3. Elementy niepozycjonowane w normalnym przepływie (block, inline).
  4. Elementy pływające (floated).
  5. Elementy pozycjonowane (relative, absolute, etc.) z z-index: auto lub z-index: 0, w kolejności pojawiania się w HTML.
  6. Potomne konteksty stosu z dodatnim z-index (najpierw te z niższym z-index).

Elementy z tą samą wartością z-index są układane w kolejności ich pojawiania się w kodzie HTML.

Zadania praktyczne

Zadanie 1 (z rozwiązaniem)

Stwórz trzy kwadratowe elementy div z position: absolute, które częściowo na siebie nachodzą. Użyj z-index, aby ułożyć je w kolejności: dolny, górny, środkowy (patrząc od spodu).

Rozwiązanie:

HTML:

<div class="sq sq1">1</div>
<div class="sq sq2">2</div>
<div class="sq sq3">3</div>

CSS:

.sq {
  position: absolute;
  width: 80px; height: 80px;
  border: 1px solid black;
  font-size: 2em; text-align: center; line-height: 80px;
}

.sq1 { background: red; top: 10px; left: 10px; z-index: 2; } /* Górny */
.sq2 { background: green; top: 30px; left: 30px; z-index: 1; } /* Dolny */
.sq3 { background: blue; top: 50px; left: 50px; z-index: 3; } /* Środkowy (na wierzchu) */

/* Poprawka: Chcemy dolny, górny, środkowy. */
/* Dolny: z-index najniższy (np. 1) */
/* Górny: z-index średni (np. 2) */
/* Środkowy: z-index najwyższy (np. 3) */

/* Poprawiony CSS: */
.sq1 { background: red; top: 10px; left: 10px; z-index: 2; } /* Górny */
.sq2 { background: green; top: 30px; left: 30px; z-index: 1; } /* Dolny */
.sq3 { background: blue; top: 50px; left: 50px; z-index: 3; } /* Środkowy */

Efekt: Niebieski kwadrat (3) będzie na wierzchu, pod nim czerwony (1), a na samym dole zielony (2).

Zadanie 2 (do samodzielnego wykonania)

Stwórz element div z position: relative; z-index: 1;. Wewnątrz niego umieść inny div z position: absolute; z-index: 100;. Obok pierwszego diva (jako jego rodzeństwo) stwórz kolejny div z position: relative; z-index: 2;. Zaobserwuj, który element jest na samym wierzchu, mimo wysokiego z-index elementu wewnętrznego.

Zadanie 3 (do samodzielnego wykonania)

Stwórz element div z position: static;. Spróbuj nadać mu z-index: 10;. Czy ma to jakikolwiek wpływ na jego kolejność nakładania?

FAQ - Najczęściej zadawane pytania

Czy z-index działa na elementach niepozycjonowanych?

Nie, właściwość z-index ma wpływ tylko na elementy, których właściwość position jest ustawiona na relative, absolute, fixed lub sticky. Jest ignorowana dla elementów z domyślnym position: static;.

Jakie są typowe wartości dla z-index?

Nie ma ścisłych reguł, ale często stosuje się pewne konwencje, np. niskie wartości (1-10) dla elementów w głównym layoucie, wyższe (10-100) dla menu rozwijanych, jeszcze wyższe (100-1000) dla dymków czy podpowiedzi, a najwyższe (np. 9999) dla okien modalnych lub nakładek na całą stronę, aby upewnić się, że są na samym wierzchu.

Czy ujemny z-index ma sens?

Tak, ujemny z-index umieszcza element **poniżej** jego rodzica (lub poniżej elementów niepozycjonowanych w tym samym kontekście stosu). Może być używany do umieszczania elementów w tle, ale należy uważać, aby nie stały się one niedostępne dla interakcji.

Co jeśli dwa elementy mają ten sam z-index?

Jeśli dwa pozycjonowane elementy w tym samym kontekście stosu mają identyczną wartość z-index, ten, który pojawia się **później w kodzie HTML**, zostanie wyrenderowany na wierzchu.