Stapelwijzigingen komen op hun plaats: vaste elementen

Tom Wiltzius
Tom Wiltzius

In Chrome 22 is het lay-outgedrag van position:fixed elementen enigszins anders dan in eerdere versies. Alle position:fixed elementen vormen nu nieuwe stapelcontexten. Hierdoor wordt de stapelvolgorde van sommige pagina's gewijzigd, waardoor de pagina-indeling kan worden verbroken. Het nieuwe gedrag komt overeen met het gedrag van WebKit-browsers op mobiele apparaten (iOS Safari en Chrome voor Android).

Stapelen Wat?

Iedereen kent en is dol op de z-index voor het bepalen van de dieptevolgorde van elementen op een pagina. Niet alle z-indexen zijn echter gelijk: de z-index van een element bepaalt alleen de volgorde ervan ten opzichte van andere elementen in dezelfde stapelcontext. De meeste elementen op een pagina bevinden zich in een enkele root-stapelcontext, maar absoluut of relatief gepositioneerde elementen met niet-automatische z-index vormen hun eigen stapelcontexten (dat wil zeggen dat al hun onderliggende elementen in de z-orde zullen worden geplaatst binnen de bovenliggende en mag niet worden afgewisseld met inhoud van buiten de ouder). Vanaf Chrome 22 zullen position:fixed elementen ook hun eigen stapelcontexten creëren.

Voor een algemeen overzicht van stapelcontexten is dit MDN-artikel geweldig om te lezen.

Vergelijk position:fixed met het nieuwe attribuut position:sticky : ter referentie: position:sticky creëert altijd een nieuwe stapelcontext.

Motivatie

Mobiele browsers (Mobiele Safari, Android-browser, op Qt gebaseerde browsers) plaatsen position:fix-elementen in hun eigen stapelcontexten en doen dat al enige tijd (sinds iOS5, Android Gingerbread, enz.) omdat het bepaalde scroll-optimalisaties mogelijk maakt, waardoor webpagina's veel reageert beter op aanraking. De wijziging wordt om drie redenen naar de desktop doorgevoerd:

  1. Het hebben van verschillend weergavegedrag in "mobiele" en "desktop" browsers is een struikelblok voor webauteurs; CSS zou waar mogelijk overal hetzelfde moeten werken.
  2. Bij tablets is het niet duidelijk welke van de 'mobiele' of 'desktop'-algoritmen voor het maken van contexten het meest geschikt is.
  3. Het overbrengen van de optimalisaties van de scrollprestaties van mobiel naar desktop is goed voor zowel gebruikers als auteurs.

Bijzonderheden van de wijziging

Hier is een voorbeeld van het verschillende lay-outgedrag: https://codepen.io/paulirish/pen/CgAof

Met de wijziging worden beide versies weergegeven als de rechterversie.

In dit voorbeeld heeft het groene vak een z-index: 1 , het roze vak heeft een z-index: 3 , en het oranje vak heeft een z-index: 2 . Het blauwe vakje is een voorloper van het oranje vakje en heeft position:fixed .

Als de blauwe doos zijn eigen stapelcontext krijgt, wordt de z-index van de oranje doos berekend ten opzichte van de stapelcontext van de blauwe doos. Omdat het blauwe vak een z-index van auto heeft, waardoor het een stapelniveau van nul heeft in de root-stapelcontext, betekent dit dat het oranje vak achter de groene en roze vakken terechtkomt, die z-indexen van 1 en 3 hebben (respectievelijk ) in de rootcontext.

Als het blauwe vak geen eigen stapelcontext krijgt, wordt de z-index van het oranje vak berekend ten opzichte van de basisstapelcontext (samen met de groene en roze vakken). Daarom wordt de oranje doos afgewisseld met de roze en groene dozen.

Voor meer details over criteria voor het maken van stapelcontexten (en hoe stapelcontexten zich in het algemeen gedragen), raadpleegt u opnieuw dit MDN-artikel . In het voorbeeld gaf de versie aan de rechterkant het blauwe vak altijd zijn eigen stapelcontext omdat de dekking ervan kleiner is dan 1. De gedragsverandering die wordt doorgevoerd, voegt effectief een ander criterium toe voor het creëren van een afzonderlijke stapelcontext, namelijk een element dat position:fixed is.

Testen en de toekomst

Om te testen of uw pagina gaat veranderen, gaat u naar Chrome's about:flags en schakelt u 'elementen met vaste positie creëren stapelcontexten' in/uit. Als uw lay-out zich in beide gevallen hetzelfde gedraagt, bent u klaar. Als dit niet het geval is, zorg er dan voor dat het er acceptabel uitziet als die vlag is ingeschakeld, want dat is de standaardinstelling in Chrome 22.

Deze wijziging verwijdert één mogelijkheid: de mogelijkheid om inhoud binnen een vaste substructuur te interleaven met niet-scrollende inhoud van buitenaf. Het is onwaarschijnlijk dat webontwikkelaars dit met opzet doen, en hetzelfde effect kan worden gecreëerd door meerdere positie:vaste elementen de verschillende delen van DOM te geven. Beschouw als voorbeeld deze twee voorbeelden:

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

Deze pagina probeert twee onderliggende div's (overlayA en overlayB) van een position:fixed-element te nemen en één boven een afzonderlijke inhoudsdiv en één onder diezelfde afzonderlijke inhoudsdiv te plaatsen. Het is nu onmogelijk om dit te doen omdat het position:fixed element zijn eigen stapelcontext is, en het (samen met al zijn onderliggende elementen) geheel boven of geheel onder de inhoudsdiv zal staan. Houd er rekening mee dat dit voorbeeld werkt in Chrome 21 en eerder, maar niet meer in Chrome 22.

Om dit op te lossen kunnen de twee overlays opgedeeld worden in hun eigen positie: vaste elementen. Elk heeft zijn eigen stapelcontext, waarvan er één boven de inhoudsdiv kan gaan en één onder de inhoudsdiv. Zie het vaste voorbeeld, dat werkt in Chrome 21 en 22:

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

De eer voor het ontstaan ​​van dit voorbeeld gaat naar de onnavolgbare hixie .

Chrome is de eerste desktopbrowser die ervoor zorgt dat position:fixed-elementen hun eigen stapelcontexten creëren. De relevante standaard is de CSS z-index-specificatie (zie bijvoorbeeld https://www.w3.org/TR/CSS21/zindex.html ). Er bestaat nog geen consensus over wat we moeten doen aan het verschil tussen mobiele en desktopbrowsers, maar gezien de verwarring van twee verschillende gedragingen op mobiel en desktop, heeft Chrome ervoor gekozen om voorlopig over te stappen op dit ene gedrag op beide platforms.

Bijgewerkt op 1 oktober 2012: De oorspronkelijke versie van dit artikel suggereerde dat de CSS z-index specificatie al was gewijzigd om het nieuwe gedrag van positie weer te geven: vaste elementen. Dit is onnauwkeurig; het is besproken op de www-style-lijst, maar tot nu toe is er geen verandering in de specificatie aangebracht.