CSS z-index en stacking contexts, uit elkaar gehaald in 3D
Gids voor CSS z-index en stacking contexts
CSS z-index werkt niet? Stacking contexts in 3D | We.Inc
Waarom z-index genegeerd wordt, elke eigenschap die een stacking context maakt, een uitvergrote 3D-weergave van de lagen, sticky headers en dropdowns, een z-index-schaal en een checklist voor debuggen.
z-index bepaalt de volgorde van overlappende elementen, maar alleen binnen dezelfde stacking context. Een kind met z-index: 9999 kan niet boven een element buiten zijn ouder uitkomen als die ouder een context vormt met een lagere z-index. Contexts ontstaan door position plus z-index, opacity onder 1, transform, filter, isolation: isolate en diverse andere eigenschappen.
Waarom z-index genegeerd lijkt te worden
Symptoom
Waarschijnlijke oorzaak
z-index heeft geen effect
Het element is position: static en geen kind van een flex- of grid-container
Enorme z-index staat nog steeds achter
Een voorouder vormt een stacking context met een lagere laag
Dropdown verborgen onder de volgende sectie
De ouder heeft transform, opacity of filter
Menu afgesneden aan de rand
overflow: hidden op een voorouder, helemaal geen z-index
De 3D-weergave hieronder haalt een kleine pagina uit elkaar in haar stacking-lagen, zodat u ziet welke vakken in welke context vastzitten. Wijzig z-index-waarden en zet de eigenschap aan of uit die op de ouder een context maakt. Daarna: elke trigger volgens MDN, sticky headers met dropdowns, een schaal met tokens en een stapsgewijze routine voor debuggen.
Stel z-index-waarden in voor de header, de kaart en de dropdown in de kaart.
Zet een trigger voor een stacking context aan op de kaart en zie hoe de dropdown vast komt te zitten.
Zet de 3D-weergave aan om de lagen gescheiden en per context gegroepeerd te zien.
Gebruik isolation: isolate of verplaats de dropdown uit de context om het op te lossen.
Zoek eerst de stacking context voordat u een getal verhoogt. De z-index verhogen binnen een context waarin het element vastzit, helpt nooit.
Bewaar z-index-waarden in benoemde tokens met ruimte ertussen, zodat nieuwe lagen ertussen passen zonder alles te hernummeren.
Gebruik isolation: isolate op componenten om hun interne z-index-waarden in te kapselen, zodat ze niet kunnen botsen met de rest van de pagina.
Voor modals en popovers gebruiken het native dialog-element en het popover-attribuut de top layer, die boven elke z-index ligt.
Veelgestelde vragen
Waarom werkt z-index niet?
Ofwel het element is niet gepositioneerd (z-index heeft een andere position dan static nodig, of een flex- of grid-ouder), ofwel het zit vast in een stacking context. De positie van de ouder in zijn eigen context bepaalt het resultaat, en kinderen kunnen daar niet aan ontsnappen, welk getal ze ook hebben.
Wat maakt een stacking context?
Het root-element, gepositioneerde elementen met een z-index, fixed en sticky elementen, flex- en grid-kinderen met een z-index, opacity onder 1, transforms, filters, clip-path, masks, mix-blend-mode, perspective, isolation: isolate, sommige waarden van contain en will-change, size containers en elementen in de top layer.
Wat doet isolation: isolate?
Het maakt een nieuwe stacking context en doet verder niets, zonder visuele verandering. Zet het op de root van een component, zodat kinderen met een negatieve z-index achter de eigen achtergrond van het component blijven in plaats van achter de pagina te vallen, en zodat de interne lagen zich nooit mengen met die van buiten.
Hoe houd ik een dropdown boven de volgende sectie?
Geef de header of container met de dropdown een hogere z-index dan de secties erna, waarbij beide gepositioneerd zijn. Als de container een transform of opacity heeft, onthoud dan dat dat een eigen context is, dus de z-index moet op die container, niet op de dropdown.
Is een negatieve z-index veilig?
Hij is geldig, maar het element komt achter de achtergrond van zijn stacking context. Zonder context op de ouder kan dat betekenen: achter de pagina-achtergrond en onzichtbaar. Voeg isolation: isolate toe op de ouder om het erbinnen te houden.
Hoe de tekenvolgorde werkt
Binnen één stacking context tekent de browser in een vaste volgorde: de eigen achtergrond van de context, dan kinderen met een negatieve z-index, dan gewone blokinhoud, floats, inline-inhoud, gepositioneerde elementen met z-index auto of 0 in bronvolgorde, en ten slotte positieve z-index van laag naar hoog.
Een kindcontext wordt als één geheel getekend op de plek van zijn ouder in die lijst. Alles binnenin wordt alleen gesorteerd ten opzichte van zijn broers en zussen. Dat is de hele reden dat een 9999 binnen een kaart met z-index: 1 verliest van een buur met z-index: 2.
Een routine voor debuggen
Bevestig eerst dat het een stacking-probleem is: als het element langs een rechte rand wordt afgesneden, zoek dan in plaats daarvan naar overflow op een voorouder. Loop daarna in DevTools omhoog vanaf het verborgen element en controleer bij elke voorouder de berekende stijlen op de triggers die op deze pagina staan.
Chromium DevTools heeft een Layers-paneel en Edge heeft een 3D View die samengestelde lagen visueel tonen. Zodra u de voorouder vindt die de context vormt, verhoog dan die voorouder, verwijder de trigger, of render het zwevende onderdeel erbuiten.
Alles wat een stacking context maakt
Gebaseerd op de MDN-referentie over stacking contexts. Eén voorwaarde is genoeg.
Triggers voor een stacking context
Eigenschap of toestand
Voorwaarde
Root-element
html is altijd de root stacking context
position: absolute of relative
Alleen met een andere z-index dan auto
position: fixed of sticky
Altijd, z-index niet nodig
Flex- of grid-kind
Met een andere z-index dan auto, ook als position static is
container-type: size of inline-size
Elk element dat een size query container is
opacity onder 1
Inclusief opacity: 0.99
Elke waarde behalve normal
transform, scale, rotate, translate
Elke waarde behalve none
filter of backdrop-filter
Elke waarde behalve none
Elke waarde behalve none
Elke waarde behalve none
mask, mask-image, mask-border
Elke waarde behalve none
isolation: isolate
Precies hiervoor gemaakt, zonder visuele bijwerkingen
Het noemen van een eigenschap die bij instellen een stacking context zou maken
layout, paint, of een shorthand die ze bevat (strict, content)
Top layer
Open modale dialog, popover, fullscreen-element en hun ::backdrop
De valkuil en de oplossingen
z-index 9999 die toch verliest
De blauwe kaart is een context met z-index 1. De tooltip erin heeft 9999, maar wordt alleen vergeleken met dingen binnen de kaart, dus het oranje vak met z-index 2 bedekt hem.
isolation: isolate houdt een negatieve laag binnen
Zonder isolate zou de decoratie met z-index: -1 achter de achtergrond van de sectie vallen en verdwijnen. Met isolate is de sectie haar eigen context.
Sticky header met een dropdown
De header is sticky en dus al een context. Geef hem een z-index boven de inhoud, en de dropdown erin erft die laag. Geen enorme getallen nodig.
Gewone inhoud
Kaarten die bij hover omhoogkomen, sticky tabelkoppen
Menu's, autocomplete-lijsten
Sticky siteheader
Achtergrond van een lade
Eigen modals (native dialog gebruikt in plaats daarvan de top layer)
Meldingen die boven alles moeten staan
Stacking-lab met uitvergrote 3D-weergave
z-index van header
z-index van kaart (of auto)
z-index van dropdown
z-index van banner
Contexttrigger op de kaart
Extra eigenschap op de kaart
Uitvergrote 3D-weergave (draai de lagen uit elkaar)
Lagen uit elkaar gehaald, hoger betekent later getekend
Platte weergave, echte CSS
Header z {z}
Kaart z {z}
Dropdown z {z}
Banner z {z}
(in de kaart)
boven de banner
onder de banner
De kaart vormt een stacking context ({why}). De {d} van de dropdown telt alleen binnen de kaart, dus hij staat {pos} omdat de kaart daar staat.
De kaart is geen stacking context, dus de dropdown concurreert rechtstreeks: {d} tegen {b} van de banner. Hij staat {pos}.
CSS voor deze opzet
CSS kopiëren
Probeer: kaart z auto, dropdown 9999, kies dan transform. Eén eigenschap zet de dropdown vast.