Sposób ułożenia zmian w elementach item:stałych

Tom Wiltzius
Tom Wiltzius

W Chrome 22 zachowanie układu elementów position:fixed jest nieco inne niż w poprzednich wersjach. Wszystkie elementy position:fixed tworzą teraz nowe konteksty nakładania. Spowoduje to zmianę kolejności nakładania się niektórych stron, co może spowodować uszkodzenie układów stron. Nowe zachowanie jest zgodne z zachowaniem przeglądarek WebKit na urządzeniach mobilnych (Safari na iOS i Chrome na Androida).

Co to jest układanie?

Każdy zna i lubi z-index, czyli sposób określania kolejności elementów na stronie. Nie wszystkie wartości z-index są jednakowe: z-index elementu określa tylko jego kolejność w stosunku do innych elementów w tym samym kontekście nakładania. Większość elementów na stronie znajduje się w jednym, głównym kontekście nakładania, ale elementy z pozycjonowaniem bezwzględnym lub względnym o wartościach z-index innych niż automatyczne tworzą własne konteksty nakładania (czyli wszystkie ich elementy podrzędne będą uporządkowane według wymiaru z oznaczeniem „z” w ramach elementu nadrzędnego i nie będą przeplatane z treściami spoza tego elementu). Od wersji 22 Chrome elementy position:fixed będą też tworzyć własne konteksty nakładania.

Ogólne informacje o nawarstwianiu kontekstów znajdziesz w tym artykule w MDN.

Porównaj position:fixednowym atrybutem position:sticky: dla wygody position:sticky zawsze tworzy nowy kontekst nakładania.

Motywacja

Przeglądarki mobilne (Mobile Safari, przeglądarka Android, przeglądarki oparte na Qt) umieszczają elementy z position:fixed w swoich własnych kontekstach układania i robią to od jakiegoś czasu (od iOS 5, Android Gingerbread itp.), ponieważ pozwala to na pewne optymalizacje przewijania, dzięki którym strony internetowe szybciej reagują na dotyk. Wprowadzamy tę zmianę na komputerach z 3 powodów:

  1. Różne zachowanie podczas renderowania w przeglądarkach „mobilnych” i „kompletnych” jest przeszkodą dla autorów stron internetowych. W miarę możliwości należy stosować CSS wszędzie w ten sam sposób.
  2. W przypadku tabletów nie jest jasne, który z algorytmów tworzenia kontekstu na podstawie obrazu nakładkowego jest bardziej odpowiedni: „komórkowy” czy „komputerowy”.
  3. Przeniesienie optymalizacji szybkości przewijania z urządzeń mobilnych na komputery jest korzystne zarówno dla użytkowników, jak i autorów.

Szczegóły zmiany

Oto przykład pokazujący różne zachowania układu: https://codepen.io/paulirish/pen/CgAof.

Po wprowadzeniu tej zmiany obie wersje będą renderowane tak jak wersja po prawej stronie.

W tym przykładzie pole zielone ma wartość z-index: 1, pole różowe – z-index: 3, a pole pomarańczowe – z-index: 2. Niebieski element jest przodkiem pomarańczowego elementu i ma position:fixed.

Jeśli niebieski element ma swój własny kontekst nakładania, wartość z-index pomarańczowego elementu jest obliczana w zależności od kontekstu nakładania niebieskiego elementu. Ponieważ niebieski element ma wartość z-index równą auto, co oznacza poziom złożenia 0 w kontekście złożenia głównego, oznacza to, że pomarańczowy element znajdzie się za zielonym i różowym elementem, które mają odpowiednio wartości 1 i 3 w kontekście głównym.

Jeśli niebieskie pole nie ma własnego kontekstu nakładania, wartość z-index pomarańczowego pola jest obliczana w stosunku do głównego kontekstu nakładania (wraz z zielonym i różowym polem). Dlatego pomarańczowe pole jest przeplatane z różowymi i zielonymi polami.

Więcej informacji o kryteriach tworzenia kontekstów nakładania (oraz o tym, jak działają konteksty nakładania) znajdziesz w tym artykule w MDN. W przykładzie wersja po prawej stronie zawsze miała własny kontekst układania dla niebieskiego pola, ponieważ jej przezroczystość była mniejsza niż 1. Zmiana zachowania sprowadza się do dodania kolejnego kryterium tworzenia oddzielnego kontekstu nakładania, a mianowicie elementu z atrybutem position:fixed.

Testowanie i przyszłość

Aby sprawdzić, czy strona się zmieni, otwórz about:flags w Chrome i włącz lub wyłącz opcję „Elementy w pozycji stałej tworzą konteksty nakładania”. Jeśli układ zachowuje się tak samo w obu przypadkach, wszystko jest w porządku. Jeśli nie, upewnij się, że włączona flaga Ci odpowiada, ponieważ będzie ona domyślna w Chrome 22.

Ta zmiana powoduje usunięcie jednej funkcji – możliwości przeplatania treści w poziomie podrzędnym position:fixed z nieprzewijalnymi treściami z zewnątrz. Jest mało prawdopodobne, aby deweloperzy stron internetowych celowo stosowali takie rozwiązanie. Ten sam efekt można uzyskać, przypisując różne części DOM do wielu elementów z atrybutem position:fixed. Rozważ te 2 przykłady:

https://codepen.io/wiltzius/pen/gcjCk

Strona próbuje umieścić 2 elementy potomne div (overlayA i overlayB) elementu position:fixed, jeden nad oddzielnym elementem div treści, a drugi pod tym samym oddzielnym elementem div treści. Obecnie jest to niemożliwe, ponieważ element position:fixed jest własnym kontekstem układania i (wraz ze wszystkimi elementami potomnymi) będzie całkowicie nad lub pod elementem div treści. Pamiętaj, że ten przykład działa w Chrome 21 i starszych wersjach, ale nie w Chrome 22.

Aby to naprawić, te 2 nakładki można podzielić na elementy z własną pozycją. Każdy z nich jest oddzielnym kontekstem układania, z którego jeden może znajdować się nad kontentem div, a drugi pod nim. Zobacz przykład z poprawkami, który działa w Chrome 21 i 22:

https://codepen.io/wiltzius/pen/vhFzG

Pomysł na ten przykład pochodzi od niepowtarzalnej hixie.

Chrome jest pierwszą przeglądarką na komputery, która powoduje, że elementy z pozycjonowaniem position:fixed tworzą własne konteksty układania. Odpowiednim standardem jest specyfikacja indeksu z-CSS (patrz np. https://www.w3.org/TR/CSS21/zindex.html). Nie ma jeszcze zgody co do tego, jak postępować z różnicami między przeglądarkami na urządzeniach mobilnych i komputerach, ale ze względu na dezorientację spowodowaną przez 2 różne zachowania na urządzeniach mobilnych i komputerach postanowiliśmy w Chrome wprowadzić na razie jedno zachowanie na obu platformach.

Zaktualizowano 1 października 2012 r.: pierwotna wersja tego artykułu sugerowała, że specyfikacja CSS z-index została już zmieniona, aby odzwierciedlić nowe zachowanie elementów z pozycją: „fixed”. To nieprawda. Rozmawialiśmy o tym w ramach listy stylów www, ale do tej pory nie wprowadziliśmy żadnych zmian w specyfikacji.