Ile warstw ma strona www?

Jaki z-index musi mieć modal, żeby był widoczny zawsze nad wszystkimi elementami? Większość frontend developerów ustawia wartość gdzieś pomiędzy 99999 a 99999999. A możemy udałoby zmieścić się w wartości poniżej 10. Poznaj stacking context - mechanizm CSSa, który warto znać.

Closeup texture layer of Rainbow cake .Delicious rainbow cake PAGES.POST.COVER_THUMBNAIL.BY_WHOM oat_autta

Z tego artykułu dowiesz się:

  • Co to jest stacking context?

  • Dlaczego z-index: 999999; nie działa?

  • Ile jest sposobów na utworzenie nowego stacking context'u?

  • Za co odpowiada właściwość CSS isolation?

Spróbuj pomyśleć o dowolnej stronie internetowej. Masz? Super, więc zadam Ci teraz proste pytanie: w ilu wymiarach została zaprojektowana? Nie zdziwiłbym się, gdyby padła odpowiedź, że w dwóch. To, co widzimy jest przecież płaskie, elementy interfejsu są poukładane w pionie i w poziomie. A co jeśli Ci powiem, że to nie do końca prawda? Strony internetowe projektowane są zawsze w trzech wymiarach i nie dlatego, że takie jest widzimisię projektantów. Programy graficzne układają nowe elementy w sposób warstwowy. Podczas implementacji jest podobnie, ale wynika to z założeń CSS i jego mechanizmu, który nazywa się stacking context.

Trzeci wymiar

Ze szkoły podstawowej zapewne pamiętasz osie x, y i z. Każda z tych osi w układzie współrzędnych pozwala określić położenie punktu. Określenie tylko jednej wartości pozwala nam na umiejscowienie punktu na jednej płaszczyźnie. Aby wyznaczyć położenie elementu w przestrzeni musimy znać wszystkie 3 wartości. Pozwala nam to bardzo dokładnie określić co się dzieje z naszym punktem.

Wyobraź sobie, że elementy HTML strony internetowej układają się wzdłuż osi z skierowanej w stronę użytkownika, który aktualnie patrzy na tę stronę www. Można śmiało powiedzieć, że układają się w przestrzeni jak warstwy, zgodnie z kolejnością priorytetów, które zostały im nadane. Im element ma wyższy priorytet, tym bliżej jest użytkownika. Takie są ogólne założenia, w zasadzie gdyby na tym poprzestać byłoby to bardzo proste.

Struktura elementów z powyższego przykładu na osi z będzie zgodna z kolejnością renderowania elementów, czyli od góry do dołu. Element o klasie item-1 będzie położony najniżej, a item-3 znajdzie się najbliżej użytkownika.

Sytuacja skomplikuje się jednak, gdy elementy HTML będą miały swoje dzieci. Wówczas ich kolejność na naszej osi z już nie będzie taka oczywista, a zarządzanie nią może stać się nie lada wyzwaniem. Na szczęście w CSS istnieje mechanizm, który to porządkuje. Stacking context (w polskiej literaturze można znaleźć określenia: stos kontekstu, kontekst układania), bo to o nim mowa, pozwala na układanie i grupowanie elementów HTML, ustalając ich pozycję początkową w oparciu o element bazowy. Który element nim będzie? To zależy. Czasami będzie to bezpośredni rodzic, czasami root dokumentu, a czasami inny „wstępny” w strukturze.

Warto tutaj dodać, że w ramach naszej strony powstanie wiele takich kontekstów, każdy z nich będzie całkowicie niezależny od swojego rodzeństwa, każdy może zawierać się w innych kontekstach a jednocześnie razem będą tworzyć hierarchiczną strukturę, która będzie swoistym podzbiorem dla struktury całego dokumentu HTML. Ważne, aby zrozumieć w jakich sytuacjach powstaną i jak je wykorzystać, ewentualnie pokonać. Wiemy wszak, że z-index: 99999; nie zawsze działa tak, jakbyśmy się tego spodziewali.

Niezrozumiany z-index

Do zarządzania stacking context’em służy właściwość css: z-index. z-index może przyjąć wartości liczbowe zarówno ujemne, jak i dodatnie. Oprócz tego może przyjąć wartość auto, która domyślnie ustawiona jest na 0 i, co ważne, nie spowoduje utworzenia nowego „stosu kontekstu”. Wartość auto jest domyślna. Zatem dodanie do z-index auto lub po prostu, go pomięcie, spowoduje, że elementy zostaną ustawione tak, jak wynikać to będzie ze struktury dokumentu HTML. W powyższym akapicie zastosowałem kilka uproszczeń, ale poniżej je doprecyzuję.

Ustawienie wartości liczbowej natomiast taki nowy kontekst zainicjuje, ale czy zawsze? Byłoby zbyt prosto, gdyby tak było. Tutaj dochodzimy do 13 przypadków, kiedy stacking context zostanie ustanowiony.

13 przypadków, które warto znać

Jak już wiemy samo ustawienie z-index nie wygeneruje nam nowego kontekstu. Jak wspomniałem, elementy zostaną umiejscowione jako warstwy w ramach najbliższego istniejącego stacking context’u. Oczywiście będziemy przeszukiwać hierarchię w górę drzewa, a gdy nie znajdziemy żadnego kontekstu dojdziemy do root’a naszego dokumentu, czyli w większości przypadków elementu <html>. To jest nasz pierwszy przypadek.

Stacking context tworzony jest zawsze dla root’a dokumentu.

Kolejne dwa przypadki dotyczą połączenia z-index oraz właściwości position. Domyślnie wszystkie elementy HTML mają pozycję statyczną (static). Zmieniając pozycję na relatywną (relative) lub absolutną (absolute) i ustawiając z-index jako wartość liczbową wyodrębnimy nowy kontekst.

W przypadku ustawienia pozycji jako fixed lub sticky, nie musimy dodawać z-index, aby powstał nowy stacking context. On powstanie prawie zawsze - wyjątkiem będzie właściwość sticky na starszych przeglądarkach desktopowych (na mobilnych nie będzie wyjątku).

Czwarty i piąty przypadek to połączenie właściwości display: flex; lub display: grid; z z-index. Szósty to ustawienie wartości mniejszej niż 1 dla właściwości opacity. Siódmy przypadek to użycie którejś z właściwości: transform, filter, backdrop-filter, perspective, clip-path, mask, mask-image lub mask-border z wartością inną niż none.

Pierwsze siedem przypadków jest dość popularnych i dlatego dość łatwo je zapamiętać. Kolejne 5 zasad, które utworzą nam nowy stacking context to:

  • właściwość container-type z wartością size lub inline-size w container query (@container),

  • właściwość mix-blend-mode z wartością inną niż normal,

  • właściwość isolation z wartością isolate,

  • właściwość contain z wartością layout lub paint, lub z wartościami złożonymi zawierającymi jedną z nich jak: content czy strict,

  • właściwość will-change, która jako wartość wskazała jakąkolwiek z właściwości, które powodują tworzenie nowych kontekstów.

Ostatni przypadek jest ciekawy. Dotyczy elementów, które znajdują się na najwyższej warstwie dokumentu oraz obejmują całą wysokość i szerokość wyświetlanego obszaru (tj. viewport’u). Elementy, które umieszczone zostaną w tej warstwie utworzą nowy kontekst wraz z odpowiadającymi im pseudo-elementami ::backdrop.

div.item-1.jpg

Spójrzmy na poniższy przykład, aby zrozumieć co się dzieje, gdy powstaje nowy kontekst.

Zasadniczo najwyższy z-index ma element o klasie modal. Jeśli spojrzymy na strukturę naszego dokumentu, to znajduje się on w elemencie <main>. Element <main> nie tworzy nowego kontekstu, ale poprzez to, że posiada pozycję relatywną pozwala nam na manipulowanie położeniem modela względem <main>. Biorąc powyższe pod uwagę nasz modal został przypisany do stacking context’u, który został utworzony na głównym elemencie, czyli na <html>. W tym samym kontekście jest umieszczony również <header>. Porównując wartości z-index obu elementów, od razu widać, że modal powinien być nad wszystkim. I rzeczywiście tak jest.

css-modal-1.png
Modal w powyższym przykładzie ma najwyższy z-index. Zarówno header, jak i modal znajdują się w tym samym stacking context.

Sytuacja zmieni się diametralnie, gdy w <main> utworzymy nowy stacking context o niższym z-index niż ma <header>.

css-modal-2.png
<main> tworzy teraz nowy stacking context, który ma niższy priorytet niż <header>. Modal znajdujący się w <main> ukrył się zatem pod nagłówkiem.

W naszym przykładzie dodanie właściwości filter tworzy nowy stacking context, który ma niższy priorytet niż <header> i umieszcza go na naszej osi z pod nim. Co ostatecznie powoduje, że nasz modal, pomimo posiadania zdecydowanie wyższego z-index, znajduje się pod nagłówkiem.

Warto też dodać, że zgodnie z ogólnymi założeniami z-index, aby zadziałał będzie potrzebował innej pozycji niż statyczna. Ta zasada ma jednak swój wyjątek - dotyczy elementów potomnych dla flexbox’a. Dzieci flexbox’a mogą używać z-index nawet, gdy mają pozycję statyczną.

Siła izolacji

Przypadków tworzenia stacking context w ramach strony www jest sporo. Większość z nich powoduje dodanie różnego rodzaje efektów ubocznych (takich jak transformacje czy zmiana sposobu wyświetlania elementów) oprócz tworzenia nowego kontekstu.

Świadome tworzenie kontekstów w ramach aplikacji internetowej może być bardzo wartościowe, ponieważ pozwala nam dokonywać wyboru nad kolejnością warstw i unikać pomyłek, których naprawienie w przyszłości może być kosztowne. W momencie, gdy chcemy utworzyć nowy stacking context i nic więcej, możemy skorzystać z niedocenianej i prawdopodobnie mało znanej właściwości isolation: isolate. Jedyną rzecz, którą wykona ta operacja, będzie utworzenie nowego contextu, tam gdzie nie powstał w wyniku innych działań.

Podsumowanie

CSS jest specyficznym językiem. Z jednej strony jest bardzo prosty i wydaje się być intuicyjny, ale posiada również wiele mechanizmów, których wcale nie musimy znać, aby w nim pisać. Pozornie możemy całe lata tworzyć kod i nie być świadomymi tego, jak on naprawdę działa. Dopiero zgłębienie tematu przy okazji „dziwnych bug'ów” pomaga nam lepiej opanować ten obszar. CSS jest też o tyle trudnym językiem, że praktycznie nie zwraca on programistom żadnej informacji o błędach, ostrzeżeniach itp. Jest jak z gumy. Co zrobimy to będzie działać, jakoś. Można się do niego przez to szczerze zniechęcić.

Stacking context to jeden z takich ukrytych mechanizmów. Poznanie i opanowanie go pozwoli nam na świadome używanie właściwości z-index, bez dziwnych zabiegów w rodzaju: z-index: 999999;.

Udostępnij ten artykuł:

Komentarze (0)

    Jeszcze nikt nic nie napisał, ale to znaczy że... możesz być pierwszy/pierwsza.

Powiązane treści

Jeżeli ten artykuł Cię zainteresował sprawdź inne materiały powiązane z nim tematycznie. Poniżej znajdziesz artykuły i odcinki podcastów mojego autorstwa oraz polecane przeze mnie książki, które rozszerzają ten temat.

Modułowy css by DegImages
Artykuł
07 sierpnia 2024

Modułowy CSS

Modularny CSS. Brzmi jak marzenie, a jednak część pracy została już wykonana i wydaje się, że jesteśmy na dobrej drodze do tego, aby to osiągnąć. Dzisiejszy artykuł opowiada historię CSS z perspektywy dążenia do tworzenia wydzielonych modułów.

Czytaj więcej
Rodziny Fontów by mediaphotos
Artykuł
09 marca 2023

Rodziny fontów

Są wszędzie. Otaczamy się nimi z każdej strony - jest ich tak dużo, że często nie zwracamy uwagę na ich różnorodność. Dziś porozmawiamy o typografii, fontach i czcionkach.

Czytaj więcej

Zapisz się do newslettera

Bądź na bieżąco z nowymi materiałami, ćwiczeniami i ciekawostkami ze świata IT. Dołącz do mnie.