Heeft u ooit z-index: 99999 ingesteld op een element in uw CSS, en komt dit niet bovenop andere elementen? Een waarde die zo groot is, zou dat element gemakkelijk visueel bovenop iets anders moeten plaatsen, ervan uitgaande dat alle verschillende elementen op een lagere waarde zijn ingesteld of helemaal niet zijn ingesteld. Een webpagina wordt meestal weergegeven in een tweedimensionale ruimte; Door specifieke CSS-eigenschappen toe te passen, wordt echter een denkbeeldig z-asvlak geïntroduceerd om diepte over te brengen. Dit vlak staat loodrecht op het scherm en van daaruit neemt de gebruiker de volgorde van de elementen waar, de een boven op de ander. Het idee achter de denkbeeldige z-as, de perceptie van de gebruiker van gestapelde elementen, is dat de CSS-eigenschappen die deze creëren, samen een zogenaamde stapelcontext vormen. We gaan het hebben over hoe elementen op een webpagina worden ‘gestapeld’, wat de stapelvolgorde bepaalt, en praktische benaderingen om elementen te ‘ontstapelen’ wanneer dat nodig is. Over het stapelen van contexten Stel je je webpagina voor als een bureau. Terwijl u HTML-elementen toevoegt, legt u de een na de ander stukjes papier op het bureau. Het laatst geplaatste stuk papier is gelijk aan het meest recent toegevoegde HTML-element en bevindt zich bovenop alle andere papieren die ervoor zijn geplaatst. Dit is de normale documentstroom, zelfs voor geneste elementen. Het bureau zelf vertegenwoordigt de root-stapelcontext, gevormd door het -element, dat alle andere mappen bevat. Nu komen specifieke CSS-eigenschappen in beeld. Eigenschappen zoals positie (met z-index), dekking, transformatie en bevatten) gedragen zich als een map. Deze map neemt een element en al zijn onderliggende elementen, haalt ze uit de hoofdstapel en groepeert ze in een afzonderlijke substapel, waardoor een zogenaamde stapelcontext ontstaat. Voor gepositioneerde elementen gebeurt dit wanneer we een andere z-indexwaarde dan auto declareren. Voor eigenschappen als dekking, transformatie en filter wordt de stapelcontext automatisch gemaakt wanneer specifieke waarden worden toegepast.

Probeer dit te begrijpen: zodra een stuk papier (dat wil zeggen een onderliggend element) zich in een map bevindt (dat wil zeggen de stapelcontext van de ouder), kan het die map nooit meer verlaten of tussen papieren in een andere map worden geplaatst. De z-index is nu alleen relevant binnen zijn eigen map.

In de onderstaande afbeelding bevindt Papier B zich nu in de stapelcontext van Map B en kan alleen worden besteld met ander papier in de map.

Stel je voor dat je twee mappen op je bureau hebt:

Map A
Map B

.map-a { z-index: 1; } .map-b { z-index: 2; }

Laten we de opmaak een beetje bijwerken. Binnenmap A is een speciale pagina, z-index: 9999. Binnenmap B is een gewone pagina, z-index: 5.

Speciale pagina

Gewone pagina

.speciale pagina { z-index: 9999; } .platte pagina {z-index: 5; }

Welke pagina staat bovenaan? Het is de .plain-pagina in map B. De browser negeert de onderliggende papieren en stapelt de twee mappen eerst. Het ziet map B (z-index: 2) en plaatst deze bovenop map A (z-index: 1), omdat we weten dat twee groter is dan één. Ondertussen staat de .special-page ingesteld op z-index: 9999-pagina onderaan de stapel, ook al is de z-index ingesteld op de hoogst mogelijke waarde. Het stapelen van contexten kan ook worden genest (mappen in mappen), waardoor een ‘stamboom’ ontstaat. Hetzelfde principe geldt: een kind kan nooit uit de map van zijn ouders ontsnappen. Nu je begrijpt hoe stapelcontexten zich gedragen als mappen die lagen groeperen en opnieuw rangschikken, is het de moeite waard om je af te vragen: waarom creëren bepaalde eigenschappen (zoals transformatie en dekking) nieuwe stapelcontexten? Het punt is: deze eigenschappen creëren geen stapelcontexten vanwege hun uiterlijk; ze doen het vanwege de manier waarop de browser onder de motorkap werkt. Wanneer je transformatie, dekking, filter of perspectief toepast, zeg je tegen de browser: "Hé, dit element kan bewegen, roteren of vervagen, dus wees voorbereid!"

Wanneer u deze eigenschappen gebruikt, maakt de browser een nieuwe stapelcontext om de weergave efficiënter te beheren. Hierdoor kan de browser animaties, transformaties en visuele effecten onafhankelijk verwerken, waardoor het minder nodig is om opnieuw te berekenen hoe deze elementen met de rest van de pagina omgaan. Zie het als de browser die zegt: "Ik behandel deze map afzonderlijk, zodat ik niet het hele bureau opnieuw hoef in te delen telkens wanneer er iets in de map verandert." Maar dat is ereen bijwerking. Zodra de browser een element naar zijn eigen laag tilt, moet hij alles daarin ‘afvlakken’, waardoor een nieuwe stapelcontext ontstaat. Het is alsof je een map van je bureau haalt om hem apart te hanteren; alles in die map wordt gegroepeerd en de browser behandelt het nu als één geheel bij het beslissen wat er bovenop komt. Dus ook al lijken de transformatie- en dekkingseigenschappen geen invloed te hebben op de manier waarop elementen visueel worden gestapeld, toch is dat wel het geval, en het is bedoeld voor prestatie-optimalisatie. Verschillende andere CSS-eigenschappen kunnen om soortgelijke redenen ook stapelcontexten creëren. MDN biedt een volledige lijst als je dieper wilt graven. Er zijn er nogal wat, wat alleen maar illustreert hoe gemakkelijk het is om onbedoeld een stapelcontext te creëren zonder het te weten. Het ‘ontstapelen’-probleem Stapelproblemen kunnen verschillende oorzaken hebben, maar sommige komen vaker voor dan andere. Modale componenten zijn een klassiek patroon omdat ze vereisen dat de component op een bovenste laag boven alle andere elementen wordt 'open', en deze vervolgens uit de bovenste laag wordt verwijderd wanneer deze 'gesloten' is. Ik ben er vrij zeker van dat we allemaal in een situatie zijn terechtgekomen waarin we een modaal openen en deze om welke reden dan ook niet verschijnt. Het is niet zo dat het niet goed is geopend, maar dat het uit het zicht is in een lagere laag van de stapelcontext. Dit laat je afvragen: "Hoe komt dat?" sinds je hebt ingesteld:

.overlay { positie: vast; /* creëert de stapelcontext */ z-index: 1; /* plaatst het element op een laag boven al het andere */ inzet: 0; breedte: 100%; hoogte: 100vh; overloop: verborgen; achtergrondkleur: #00000080; }

Dit lijkt correct, maar als het bovenliggende element dat de modale trigger bevat een onderliggend element is binnen een ander ouderelement dat ook is ingesteld op z-index: 1, wordt het modale element technisch gezien in een sublaag geplaatst die wordt verborgen door de hoofdmap. Laten we eens kijken naar dat specifieke scenario en een paar andere veelvoorkomende valkuilen bij het stapelen van contexten. Ik denk dat je niet alleen zult zien hoe gemakkelijk het is om onbedoeld stapelcontexten te creëren, maar ook hoe je deze verkeerd kunt beheren. Hoe u terugkeert naar een beheerde staat, hangt ook af van de situatie. Scenario 1: Het gevangen modaal

U kunt onmiddellijk zien dat uw modaal vastzit in een laag op een laag niveau en de ouder identificeert. Browser-extensies Slimme ontwikkelaars hebben extensies gebouwd om te helpen. Tools zoals deze Chrome-extensie "CSS Stacking Context Inspector" voegen een extra z-index-tabblad toe aan uw DevTools om u informatie te tonen over elementen die een stapelcontext creëren.

IDE-extensies U kunt zelfs problemen tijdens de ontwikkeling opmerken met een extensie zoals deze voor VS Code, die potentiële stapelcontextproblemen rechtstreeks in uw editor belicht.

Ontstapelen en de controle herwinnen Nadat we de oorzaak hebben geïdentificeerd, is de volgende stap het aanpakken ervan. Er zijn verschillende manieren waarop u dit probleem kunt aanpakken, en ik zal ze in volgorde opsommen. Je kunt echter iedereen op elk niveau kiezen; niemand kan klagen of een ander tegenwerken. Verander de HTML-structuur Dit wordt als de optimale oplossing beschouwd. Om een ​​stapelcontextprobleem tegen te komen, moet je een aantal elementen op grappige posities in je HTML hebben geplaatst. Door de pagina te herstructureren, kunt u de DOM opnieuw vormgeven en het stapelcontextprobleem elimineren. Zoek het problematische element en verwijder het uit het trapping-element in de HTML-opmaak. We kunnen bijvoorbeeld het eerste scenario, ‘The Trapped Modal’, oplossen door de .modal-container uit de header te verplaatsen en deze zelf in het -element te plaatsen.

Koptekst

Hoofdinhoud

Deze inhoud heeft een z-index van 2 en dekt nog steeds niet de modale inhoud.

Wanneer u op de knop ‘Open Modal’ klikt, wordt de modal vóór al het andere geplaatst, zoals het hoort te zijn. Zie Penscenario 1: The Trapped Modal (Solution) [gevorkt] door Shoyombo Gabriel Ayomide. Pas de aanBovenliggende stapelcontext in CSS Wat als het element een element is dat u niet kunt verplaatsen zonder de lay-out te verbreken? Het is beter om het probleem aan te pakken: de ouder bepaalt de context. Zoek de CSS-eigenschap (of eigenschappen) die verantwoordelijk is voor het activeren van de context en verwijder deze. Als het een doel heeft en niet kan worden verwijderd, geef de ouder dan een hogere z-indexwaarde dan de zusterelementen om de hele container op te tillen. Bij een hogere z-indexwaarde wordt de bovenliggende container naar boven verplaatst en verschijnen de onderliggende containers dichter bij de gebruiker. Gebaseerd op wat we hebben geleerd in het scenario ‘The Submerged Dropdown’, kunnen we de vervolgkeuzelijst niet uit de navigatiebalk verplaatsen; het zou geen zin hebben. We kunnen de z-indexwaarde van de .navbar-container echter verhogen zodat deze groter is dan de z-indexwaarde van het .content-element. .navbar { achtergrond: #333; /* z-index: 1; */ z-index: 3; positie: relatief; }

Met deze wijziging verschijnt het .dropdown-menu nu zonder enig probleem voor de inhoud. Zie penscenario 2: de ondergedompelde dropdown (oplossing) [gevorkt] door Shoyombo Gabriel Ayomide. Probeer Portals, als u een raamwerk gebruikt In raamwerken zoals React of Vue is een portal een functie waarmee u een component buiten de normale bovenliggende hiërarchie in de DOM kunt weergeven. Portalen zijn als een teleportatieapparaat voor uw componenten. Hiermee kunt u de HTML van een component overal in het document weergeven (meestal rechtstreeks in document.body), terwijl deze logisch verbonden blijft met de oorspronkelijke ouder voor rekwisieten, statussen en gebeurtenissen. Dit is perfect om te ontsnappen aan stapelcontext-traps, omdat de weergegeven uitvoer letterlijk buiten de problematische bovenliggende container verschijnt. ReactDOM.createPortal( , document.body );

Dit zorgt ervoor dat de inhoud van uw vervolgkeuzelijst niet verborgen is achter het bovenliggende item, zelfs als het bovenliggende item overflow heeft: verborgen of een lagere z-index. In het “The Clipped Tooltip”-scenario waar we eerder naar keken, gebruikte ik een portal om de tooltip te redden van de overflow: verborgen clip door deze in de documenttekst te plaatsen en boven de trigger in de container te plaatsen. Zie Penscenario 3: De geknipte tooltip (oplossing) [gevorkt] door Shoyombo Gabriel Ayomide. Introductie van stapelcontext zonder bijwerkingen Alle benaderingen die in de vorige sectie zijn uitgelegd, zijn gericht op het ‘ontstapelen’ van elementen uit problematische stapelcontexten, maar er zijn enkele situaties waarin u daadwerkelijk een stapelcontext moet of wilt creëren. Het creëren van een nieuwe stapelcontext is eenvoudig, maar alle benaderingen hebben een neveneffect. Dat wil zeggen, behalve bij het gebruik van isolatie: isoleren. Wanneer toegepast op een element, wordt de stapelcontext van de onderliggende elementen van dat element bepaald ten opzichte van elk kind en binnen die context, in plaats van te worden beïnvloed door elementen daarbuiten. Een klassiek voorbeeld is het toekennen van een negatieve waarde aan dat element, zoals z-index: -1. Stel je voor dat je een .card-component hebt. U wilt een decoratieve vorm toevoegen die achter de tekst van de .card staat, maar bovenop de achtergrond van de kaart. Zonder een stapelcontext op de kaart stuurt z-index: -1 de vorm naar de onderkant van de hoofdstapelcontext (de hele pagina). Hierdoor verdwijnt het achter de witte achtergrond van de .card: Zie de Pen Negatieve z-index (probleem) [gevorkt] door Shoyombo Gabriel Ayomide. Om dit op te lossen, verklaren we isolation: isolate op de parent .card: Zie de Pen Negative z-index (oplossing) [gevorkt] door Shoyombo Gabriel Ayomide. Nu wordt het .card-element zelf een stapelcontext. Wanneer zijn onderliggende element (de decoratieve vorm gemaakt op het :before pseudo-element) een z-index heeft: -1, gaat het helemaal onderaan de stapelcontext van het bovenliggende element. Het zit perfect achter de tekst en bovenop de achtergrond van de kaart, zoals bedoeld. Conclusie Onthoud: de volgende keer dat uw z-index uit de hand lijkt te lopen, is het een gevangen stapelcontext. Referenties

Context stapelen (MDN) Z-index en stapelcontexten (web.dev) “Hoe je een nieuwe stapelcontext creëert met de isolatie-eigenschap in CSS”, Natalie Pina "Wat maakt het uit, z-index ???", Josh Comeau

Verder lezen over SmashingMag

“CSS Z-Index beheren in grote projecten”, Steven Frieson “Kleverige headers en elementen op volledige hoogte: een lastige combinatie”, Philip Braunen “Z-Index beheren in een op componenten gebaseerde webapplicatie”, Pavel Pomerantsev “De Z-Index CSS-eigenschap: een alomvattend overzicht”, Louis Lazaris

You May Also Like

Enjoyed This Article?

Get weekly tips on growing your audience and monetizing your content — straight to your inbox.

No spam. Join 138,000+ creators. Unsubscribe anytime.

Create Your Free Bio Page

Join 138,000+ creators on Seemless.

Get Started Free