Har du noen gang satt z-index: 99999 på et element i CSS, og det kommer ikke ut over andre elementer? En verdi som er stor, bør enkelt plassere det elementet visuelt oppå alt annet, forutsatt at alle de forskjellige elementene er satt til enten en lavere verdi eller ikke satt i det hele tatt. En nettside er vanligvis representert i et todimensjonalt rom; imidlertid, ved å bruke spesifikke CSS-egenskaper, introduseres et imaginært z-akseplan for å formidle dybde. Dette planet er vinkelrett på skjermen, og fra det oppfatter brukeren rekkefølgen på elementene, den ene oppå den andre. Ideen bak den imaginære z-aksen, brukerens oppfatning av stablede elementer, er at CSS-egenskapene som skaper den kombineres for å danne det vi kaller en stablekontekst. Vi skal snakke om hvordan elementer "stables" på en nettside, hva som styrer stablingsrekkefølgen, og praktiske tilnærminger til "unstable" elementer når det er nødvendig. Om stablingskontekster Se for deg nettsiden din som et skrivebord. Når du legger til HTML-elementer, legger du papirbiter etter hverandre på skrivebordet. Det siste stykket papir som er plassert tilsvarer det sist lagt til HTML-elementet, og det ligger oppå alle de andre papirene som er plassert foran det. Dette er den normale dokumentflyten, selv for nestede elementer. Selve skrivebordet representerer rotstablingskonteksten, dannet av -elementet, som inneholder alle andre mapper. Nå kommer spesifikke CSS-egenskaper inn. Egenskaper som posisjon (med z-indeks), opasitet, transformering og inneholde) fungerer som en mappe. Denne mappen tar et element og alle dets underordnede elementer, trekker dem ut fra hovedstabelen og grupperer dem i en separat understabel, og skaper det vi kaller en stablekontekst. For posisjonerte elementer skjer dette når vi erklærer en annen z-indeksverdi enn auto. For egenskaper som opasitet, transformasjon og filter, opprettes stablekonteksten automatisk når spesifikke verdier brukes.
Prøv å forstå dette: Når et stykke papir (dvs. et underordnet element) er inne i en mappe (dvs. forelderens stablekontekst), kan det aldri gå ut av mappen eller plasseres mellom papirer i en annen mappe. Dens z-indeks er nå bare relevant i sin egen mappe.
I illustrasjonen nedenfor er papir B nå innenfor stablekonteksten til mappe B, og kan kun bestilles med andre papirer i mappen.
Tenk deg, om du vil, at du har to mapper på skrivebordet ditt:
.folder-a { z-indeks: 1; } .mappe-b { z-indeks: 2; }
La oss oppdatere markeringen litt. Inne i mappe A er en spesiell side, z-indeks: 9999. Inne i mappe B er en vanlig side, z-indeks: 5.
.special-page { z-indeks: 9999; } .plain-page { z-indeks: 5; }
Hvilken side er øverst? Det er .plain-siden i mappe B. Nettleseren ignorerer underordnede papirer og stabler de to mappene først. Den ser mappe B (z-indeks: 2) og plasserer den på toppen av mappe A (z-indeks: 1) fordi vi vet at to er større enn én. I mellomtiden er .special-page satt til z-index: 9999-siden nederst i stabelen selv om z-indeksen er satt til høyest mulig verdi. Stablekontekster kan også nestes (mapper inne i mapper), og skape et "slektstre." Det samme prinsippet gjelder: et barn kan aldri unnslippe foreldrenes mappe. Nå som du forstår hvordan stablingskontekster oppfører seg som mapper som grupperer og omorganiserer lag, er det verdt å spørre: hvorfor skaper visse egenskaper – som transformasjon og opasitet – nye stablingskontekster? Her er tingen: disse egenskapene skaper ikke stablingskontekster på grunn av hvordan de ser ut; de gjør det på grunn av hvordan nettleseren fungerer under panseret. Når du bruker transformasjon, opasitet, filter eller perspektiv, forteller du nettleseren: "Hei, dette elementet kan flytte, rotere eller falme, så vær klar!"
Når du bruker disse egenskapene, oppretter nettleseren en ny stablingskontekst for å administrere gjengivelsen mer effektivt. Dette lar nettleseren håndtere animasjoner, transformasjoner og visuelle effekter uavhengig, noe som reduserer behovet for å beregne på nytt hvordan disse elementene samhandler med resten av siden. Tenk på det som at nettleseren sier: "Jeg skal håndtere denne mappen separat, slik at jeg ikke trenger å stokke om hele skrivebordet hver gang noe i den endres." Men det er deten bivirkning. Når nettleseren løfter et element inn i sitt eget lag, må det "flate" alt i det, og skape en ny stablingskontekst. Det er som å ta en mappe fra skrivebordet for å håndtere den separat; alt inne i den mappen blir gruppert, og nettleseren behandler den nå som en enkelt enhet når den bestemmer hva som skal ligge på toppen av hva. Så selv om transformasjons- og opasitetsegenskapene kanskje ikke ser ut til å påvirke måten elementer stables visuelt på, gjør de det, og det er for ytelsesoptimalisering. Flere andre CSS-egenskaper kan også lage stablingskontekster av lignende årsaker. MDN gir en komplett liste hvis du ønsker å grave dypere. Det er ganske mange, som bare illustrerer hvor enkelt det er å utilsiktet lage en stablekontekst uten å vite det. Problemet med "Avstabling". Stablingsproblemer kan oppstå av mange årsaker, men noen er mer vanlige enn andre. Modale komponenter er et klassisk mønster fordi de krever å bytte komponenten til å "åpne" på et topplag over alle andre elementer, og deretter fjerne det fra topplaget når det er "lukket". Jeg er ganske sikker på at vi alle har havnet i en situasjon der vi åpner en modal og, uansett grunn, dukker den ikke opp. Det er ikke det at den ikke åpnet seg ordentlig, men at den er ute av syne i et lavere lag av stablekonteksten. Dette får deg til å lure på "hvordan?" siden du satte:
.overlay { posisjon: fast; /* oppretter stablekonteksten */ z-indeks: 1; /* legger elementet på et lag over alt annet */ innfelt: 0; bredde: 100 %; høyde: 100vh; overløp: skjult; bakgrunnsfarge: #00000080; }
Dette ser riktig ut, men hvis det overordnede elementet som inneholder den modale utløseren er et underordnet element i et annet overordnet element som også er satt til z-index: 1, som teknisk sett plasserer modalen i et underlag skjult av hovedmappen. La oss se på det spesifikke scenariet og et par andre vanlige fallgruver i stablingskontekst. Jeg tror du ikke bare vil se hvor enkelt det er å utilsiktet lage stablingskontekster, men også hvordan du feilbehandler dem. Hvordan du går tilbake til en administrert tilstand avhenger også av situasjonen. Scenario 1: The Trapped Modal
Du kan umiddelbart se din modal fanget i et lavnivålag og identifisere forelderen. Nettleserutvidelser Smarte utviklere har bygget utvidelser for å hjelpe. Verktøy som denne "CSS Stacking Context Inspector" Chrome-utvidelsen legger til en ekstra z-indeks-fane til DevTools for å vise deg informasjon om elementer som skaper en stablingskontekst.
IDE-utvidelser Du kan til og med oppdage problemer under utvikling med en utvidelse som denne for VS Code, som fremhever potensielle stablingskontekstproblemer direkte i redigeringsprogrammet.
Avstabling og gjenvinne kontroll Etter at vi har identifisert grunnårsaken, er neste trinn å håndtere den. Det er flere tilnærminger du kan ta for å takle dette problemet, og jeg vil liste dem opp i rekkefølge. Du kan velge hvem som helst på alle nivåer; ingen kan klage eller hindre en annen. Endre HTML-strukturen Dette anses som den optimale løsningen. For at du skal støte på et stablingskontekstproblem, må du ha plassert noen elementer i morsomme posisjoner i HTML-en din. Å restrukturere siden vil hjelpe deg å omforme DOM og eliminere stablingskontekstproblemet. Finn det problematiske elementet og fjern det fra overlappingselementet i HTML-markeringen. For eksempel kan vi løse det første scenariet, "The Trapped Modal," ved å flytte .modal-containeren ut av headeren og plassere den i
-elementet av seg selv.Dette innholdet har en z-indeks på 2 og vil fortsatt ikke dekke modalen.Overskrift
Hovedinnhold
Når du klikker på "Åpne Modal"-knappen, er modalen plassert foran alt annet som det skal være. Se Pen Scenario 1: The Trapped Modal (Solution) [forked] av Shoyombo Gabriel Ayomide. JusterForeldrestablingskontekst i CSS Hva om elementet er et du ikke kan flytte uten å bryte oppsettet? Det er bedre å ta opp problemet: forelderen etablerer konteksten. Finn CSS-egenskapen (eller -egenskapene) som er ansvarlige for å utløse konteksten, og fjern den. Hvis det har et formål og ikke kan fjernes, gi forelderen en høyere z-indeksverdi enn søskenelementene for å løfte hele beholderen. Med en høyere z-indeksverdi flyttes den overordnede beholderen til toppen, og dens underordnede vises nærmere brukeren. Basert på det vi lærte i "The Submerged Dropdown"-scenario, kan vi ikke flytte rullegardinmenyen ut av navigasjonslinjen; det ville ikke gi mening. Vi kan imidlertid øke z-indeksverdien til .navbar-beholderen til å være større enn .content-elementets z-indeksverdi. .navbar { bakgrunn: #333; /* z-indeks: 1; */ z-indeks: 3; stilling: pårørende; }
Med denne endringen vises nå rullegardinmenyen foran innholdet uten problemer.
Se Pen Scenario 2: The Submerged Dropdown (Solution) [forked] av Shoyombo Gabriel Ayomide.
Prøv portaler hvis du bruker et rammeverk
I rammeverk som React eller Vue er en portal en funksjon som lar deg gjengi en komponent utenfor dets normale overordnede hierarki i DOM. Portaler er som en teleporteringsenhet for komponentene dine. De lar deg gjengi en komponents HTML hvor som helst i dokumentet (vanligvis rett inn i document.body) mens du holder den logisk koblet til den opprinnelige forelderen for rekvisitter, tilstand og hendelser. Dette er perfekt for å unnslippe stablingskontekstfeller siden det gjengitte utdata bokstavelig talt vises utenfor den problematiske overordnede beholderen.
ReactDOM.createPortal(
Dette sikrer at rullegardininnholdet ditt ikke er skjult bak overordnet, selv om forelderen har overløp: skjult eller en lavere z-indeks. I scenariet "Det klippede verktøytipset" vi så på tidligere, brukte jeg en portal for å redde verktøytipset fra overløpet: skjult klipp ved å plassere det i dokumentteksten og plassere det over utløseren i beholderen. Se pennscenario 3: The Clipped Tooltip (Solution) [forked] av Shoyombo Gabriel Ayomide. Vi introduserer stablingskontekst uten bivirkninger Alle tilnærmingene som ble forklart i forrige seksjon er rettet mot å "avstable" elementer fra problematiske stablingskontekster, men det er noen situasjoner der du faktisk trenger eller ønsker å lage en stablingskontekst. Det er enkelt å lage en ny stablekontekst, men alle tilnærminger har en bieffekt. Det vil si, bortsett fra å bruke isolasjon: isolat. Når den brukes på et element, bestemmes stablekonteksten til det elementets barn i forhold til hvert barn og innenfor den konteksten, i stedet for å bli påvirket av elementer utenfor det. Et klassisk eksempel er å tildele dette elementet en negativ verdi, for eksempel z-indeks: -1. Tenk deg at du har en .card-komponent. Du vil legge til en dekorativ form som sitter bak .card-teksten, men på toppen av kortets bakgrunn. Uten en stablekontekst på kortet, sender z-index: -1 formen til bunnen av rotstablingskonteksten (hele siden). Dette gjør at den forsvinner bak .cards hvite bakgrunn: Se Pen Negative z-index (problem) [forked] av Shoyombo Gabriel Ayomide. For å løse dette, erklærer vi isolasjon: isolat på det overordnede .card: Se Pen Negative z-index (løsning) [forked] av Shoyombo Gabriel Ayomide. Nå blir selve .card-elementet en stablekontekst. Når dets underordnede element - den dekorative formen skapt på :before pseudo-elementet - har z-indeks: -1, går det helt til bunnen av foreldrenes stablekontekst. Den sitter perfekt bak teksten og på toppen av kortets bakgrunn, som ment. Konklusjon Husk: neste gang z-indeksen din virker ute av kontroll, er det en fanget stablingskontekst. Referanser
Stablekontekst (MDN) Z-indeks og stablingskontekster (web.dev) "Hvordan lage en ny stablingskontekst med isolasjonsegenskapen i CSS", Natalie Pina "Hva i helvete, z-indeks?", Josh Comeau
Mer lesing på SmashingMag
"Administrere CSS Z-Index i store prosjekter", Steven Frieson "Klebrige overskrifter og elementer i full høyde: En vanskelig kombinasjon", Philip Braunen "Administrere Z-indeks i en komponentbasert nettapplikasjon", Pavel Pomerantsev "Z-Index CSS Property: A Comprehensive Look", Louis Lazaris