Jeste li ikada postavili z-index: 99999 na element u svom CSS-u, a on se ne prikazuje iznad ostalih elemenata? Tako velika vrijednost trebala bi lako postaviti taj element vizualno iznad bilo čega drugog, pod pretpostavkom da su svi različiti elementi postavljeni na nižu vrijednost ili da uopće nisu postavljeni. Web stranica je obično predstavljena u dvodimenzionalnom prostoru; međutim, primjenom specifičnih CSS svojstava, uvodi se zamišljena ravnina z-osi da bi se prenijela dubina. Ta je ravnina okomita na ekran i iz nje korisnik percipira redoslijed elemenata, jedan na vrhu drugoga. Ideja koja stoji iza zamišljene z-osi, korisničke percepcije naslaganih elemenata, jest da se CSS svojstva koja je stvaraju kombiniraju i tvore ono što nazivamo kontekstom slaganja. Razgovarat ćemo o tome kako su elementi "složeni" na web-stranici, što kontrolira redoslijed slaganja i praktičnim pristupima za "odlaganje" elemenata kada je potrebno. O kontekstima slaganja Zamislite svoju web stranicu kao radni stol. Dok dodajete HTML elemente, polažete komade papira, jedan za drugim, na stol. Posljednji stavljeni komad papira ekvivalentan je posljednjem dodanom HTML elementu i nalazi se na vrhu svih ostalih papira stavljenih prije njega. Ovo je normalan tijek dokumenta, čak i za ugniježđene elemente. Sama radna površina predstavlja korijenski kontekst slaganja, formiran elementom , koji sadrži sve ostale mape. Sada na scenu stupaju određena CSS svojstva. Svojstva poput položaja (sa z-indeksom), neprozirnosti, transformacije i sadržavanja) ponašaju se kao mapa. Ova mapa uzima element i svu njegovu djecu, izvlači ih iz glavnog stoga i grupira u zasebni podskup, stvarajući ono što nazivamo kontekst slaganja. Za pozicionirane elemente to se događa kada deklariramo vrijednost z-indeksa koja nije auto. Za svojstva poput neprozirnosti, transformacije i filtra, kontekst slaganja stvara se automatski kada se primijene određene vrijednosti.
Pokušajte ovo razumjeti: jednom kada se komad papira (tj. podređeni element) nađe unutar mape (tj. roditeljskog konteksta slaganja), više nikada ne može izaći iz te mape ili biti smješten između papira u drugoj mapi. Njegov z-index sada je relevantan samo unutar vlastite mape.
Na slici ispod, papir B sada je unutar konteksta slaganja mape B i može se naručiti samo s drugim papirima u mapi.
Zamislite, ako želite, da imate dvije mape na svom stolu:
.folder-a { z-index: 1; } .folder-b { z-index: 2; }
Hajdemo malo ažurirati oznake. Unutar mape A je posebna stranica, z-indeks: 9999. Unutar mape B je obična stranica, z-indeks: 5.
.posebna-stranica { z-index: 9999; } .plain-page { z-index: 5; }
Koja je stranica na vrhu? To je .plain-stranica u mapi B. Preglednik ignorira podređene papire i prvo slaže dvije mape. Vidi mapu B (z-indeks: 2) i postavlja je na vrh mape A (z-indeks: 1) jer znamo da je dva veće od jedan. U međuvremenu, stranica .special-page postavljena na z-index: 9999 nalazi se na dnu hrpe iako je njen z-index postavljen na najveću moguću vrijednost. Konteksti slaganja također mogu biti ugniježđeni (mape unutar mapa), stvarajući "obiteljsko stablo". Primjenjuje se isti princip: dijete nikada ne može pobjeći iz mape svojih roditelja. Sada kada ste shvatili kako se konteksti slaganja ponašaju poput mapa koje grupiraju i mijenjaju redoslijed slojeva, vrijedi se zapitati: zašto određena svojstva — poput transformacije i neprozirnosti — stvaraju nove kontekste slaganja? Evo o čemu se radi: ova svojstva ne stvaraju kontekste slaganja zbog toga kako izgledaju; oni to rade zbog načina na koji preglednik radi ispod haube. Kada primijenite transformaciju, neprozirnost, filtar ili perspektivu, govorite pregledniku: "Hej, ovaj bi se element mogao pomaknuti, rotirati ili izblijediti, stoga budite spremni!"
Kada koristite ta svojstva, preglednik stvara novi kontekst slaganja radi učinkovitijeg upravljanja iscrtavanjem. To pregledniku omogućuje samostalno rukovanje animacijama, transformacijama i vizualnim efektima, smanjujući potrebu za ponovnim izračunavanjem načina na koji ti elementi međusobno djeluju s ostatkom stranice. Zamislite to kao preglednik koji govori: "Rukovat ću ovom mapom zasebno tako da ne moram mijenjati cijeli radni stol svaki put kad se nešto na njemu promijeni." Ali postojinuspojava. Nakon što preglednik podigne element u vlastiti sloj, mora "spljoštiti" sve unutar njega, stvarajući novi kontekst slaganja. To je kao da uzmete fascikl sa stola da biste njime zasebno upravljali; sve unutar te mape se grupira, a preglednik to sada tretira kao jednu jedinicu kada odlučuje što će biti iznad čega. Pa iako se možda čini da svojstva transformacije i neprozirnosti ne utječu na način na koji se elementi vizualno slažu, utječu, i to radi optimizacije izvedbe. Nekoliko drugih CSS svojstava također mogu stvoriti kontekste slaganja iz sličnih razloga. MDN nudi potpuni popis ako želite kopati dublje. Ima ih dosta, što samo ilustrira koliko je lako nenamjerno stvoriti kontekst slaganja, a da to ne znate. Problem "rasklapanja". Problemi sa slaganjem mogu nastati iz mnogo razloga, ali neki su češći od drugih. Modalne komponente klasičan su obrazac jer zahtijevaju prebacivanje komponente da se "otvori" na gornjem sloju iznad svih ostalih elemenata, a zatim je uklonite s gornjeg sloja kada je "zatvorena". Prilično sam uvjeren da smo se svi našli u situaciji kada smo otvorili modal i, iz bilo kojeg razloga, on se ne pojavi. Ne radi se o tome da se nije pravilno otvorio, već da je izvan vidokruga u nižem sloju konteksta slaganja. To vas ostavlja da se zapitate "kako to?" budući da ste postavili:
.overlay { položaj: fiksni; /* stvara kontekst slaganja */ z-indeks: 1; /* stavlja element na sloj iznad svega ostalog */ umetak: 0; širina: 100%; visina: 100vh; preljev: skriven; boja pozadine: #00000080; }
Ovo izgleda ispravno, ali ako je nadređeni element koji sadrži modalni okidač podređeni element unutar drugog nadređenog elementa koji je također postavljen na z-index: 1, to tehnički smješta modal u podsloj koji je zaklonjen glavnom mapom. Pogledajmo taj specifični scenarij i nekoliko drugih uobičajenih zamki konteksta slaganja. Mislim da ćete vidjeti ne samo koliko je lako nenamjerno stvoriti kontekste slaganja, već i kako njima loše upravljati. Također, način na koji ćete se vratiti u upravljano stanje ovisi o situaciji. Scenarij 1: Zarobljeni modal
Možete odmah vidjeti svoj modal zarobljen u sloju niske razine i identificirati roditelja. Proširenja preglednika Pametni programeri izgradili su proširenja za pomoć. Alati kao što je ovo Chromeovo proširenje "CSS Stacking Context Inspector" dodaju dodatnu karticu z-indeksa u vaše DevTools kako bi vam prikazali informacije o elementima koji stvaraju kontekst slaganja.
IDE ekstenzije Čak možete uočiti probleme tijekom razvoja pomoću proširenja poput ovog za VS Code, koje naglašava potencijalne probleme s kontekstom slaganja izravno u vašem uređivaču.
Skidanje i vraćanje kontrole Nakon što smo identificirali temeljni uzrok, sljedeći korak je rješavanje toga. Postoji nekoliko pristupa koje možete poduzeti da biste riješili ovaj problem, a ja ću ih navesti redom. Međutim, možete odabrati bilo koga na bilo kojoj razini; nitko se ne može žaliti ili opstruirati drugoga. Promjena HTML strukture Ovo se smatra optimalnim rješenjem. Da biste naišli na problem s kontekstom slaganja, morali ste postaviti neke elemente na smiješne položaje unutar svog HTML-a. Restrukturiranje stranice pomoći će vam da preoblikujete DOM i eliminirate problem konteksta slaganja. Pronađite problematični element i uklonite ga iz trapping elementa u HTML označavanju. Na primjer, možemo riješiti prvi scenarij, “The Trapped Modal,” premještanjem .modal-container-a iz zaglavlja i stavljanjem samog u element
.Ovaj sadržaj ima z-indeks 2 i još uvijek neće pokriti modal.Zaglavlje
Glavni sadržaj
Kada kliknete gumb "Otvori modal", modal se postavlja ispred svega ostalog kao što bi trebao biti. Pogledajte scenarij olovke 1: The Trapped Modal (Rješenje) [forked] Shoyombo Gabriel Ayomide. PodesiteRoditeljski kontekst slaganja u CSS-u Što ako je element onaj koji ne možete premjestiti bez narušavanja izgleda? Bolje je riješiti problem: roditelj uspostavlja kontekst. Pronađite CSS svojstvo (ili svojstva) odgovorno za pokretanje konteksta i uklonite ga. Ako ima svrhu i ne može se ukloniti, dajte nadređenom višu vrijednost z-indeksa od srodnih elemenata za podizanje cijelog spremnika. S višom vrijednošću z-indeksa, nadređeni spremnik pomiče se na vrh, a njegovi potomci se čine bliže korisniku. Na temelju onoga što smo naučili u scenariju "Potopljeni padajući izbornik", ne možemo pomaknuti padajući izbornik izvan navigacijske trake; ne bi imalo smisla. Međutim, možemo povećati vrijednost z-indexa .navbar spremnika tako da bude veća od vrijednosti z-indexa elementa .content. .navbar { pozadina: #333; /* z-indeks: 1; */ z-indeks: 3; položaj: relativan; }
Uz ovu promjenu, padajući izbornik sada se pojavljuje ispred sadržaja bez ikakvih problema.
Pogledajte scenarij olovke 2: The Submerged Dropdown (Solution) [forked] by Shoyombo Gabriel Ayomide.
Isprobajte portale, ako koristite okvir
U okvirima kao što su React ili Vue, portal je značajka koja vam omogućuje renderiranje komponente izvan njezine normalne nadređene hijerarhije u DOM-u. Portali su poput uređaja za teleportaciju vaših komponenti. Omogućuju vam da renderirate HTML komponente bilo gdje u dokumentu (obično izravno u document.body) dok ga održavate logički povezanim s izvornim roditeljem za rekvizite, stanje i događaje. Ovo je savršeno za izbjegavanje zamki konteksta slaganja budući da se renderirani izlaz doslovno pojavljuje izvan problematičnog nadređenog spremnika.
ReactDOM.createPortal(
Ovo osigurava da vaš padajući sadržaj nije skriven iza nadređenog, čak i ako nadređeni ima preljev: skriven ili niži z-indeks. U scenariju "Izrezani opis alata" koji smo ranije pogledali, upotrijebio sam portal da spasim opis alata od overflow: skrivenog isječka tako što sam ga postavio u tijelo dokumenta i postavio iznad okidača unutar spremnika. Pogledajte scenarij olovke 3: Izrezani opis alata (rješenje) [račvano] autora Shoyomba Gabriela Ayomidea. Predstavljamo kontekst slaganja bez nuspojava Svi pristupi objašnjeni u prethodnom odjeljku usmjereni su na "odvajanje" elemenata iz problematičnih konteksta slaganja, ali postoje neke situacije u kojima ćete zapravo trebati ili željeti stvoriti kontekst slaganja. Stvaranje novog konteksta slaganja je jednostavno, ali svi pristupi imaju nuspojave. To jest, osim za korištenje izolacije: izolirati. Kada se primijeni na element, kontekst slaganja djece tog elementa određuje se u odnosu na svako dijete i unutar tog konteksta, umjesto da na njega utječu elementi izvan njega. Klasičan primjer je dodjeljivanje negativne vrijednosti tom elementu, kao što je z-index: -1. Zamislite da imate komponentu .card. Želite dodati ukrasni oblik koji se nalazi iza teksta .kartice, ali na vrhu pozadine kartice. Bez konteksta slaganja na kartici, z-index: -1 šalje oblik na dno korijenskog konteksta slaganja (cijela stranica). Zbog toga nestaje iza bijele pozadine .card-a: Pogledajte Pen Negative z-index (problem) [forked] Shoyombo Gabriel Ayomide. Da bismo to riješili, deklariramo izolaciju: isolate na nadređenoj .card: Pogledajte Pen Negative z-index (rješenje) [forked] Shoyombo Gabriel Ayomide. Sada sam element .card postaje kontekst slaganja. Kada njegov podređeni element — ukrasni oblik stvoren na pseudoelementu :before — ima z-index: -1, ide na samo dno nadređenog konteksta slaganja. Savršeno stoji iza teksta i na vrhu pozadine čestitke, kako je i predviđeno. Zaključak Zapamtite: sljedeći put kada vam se z-indeks čini izvan kontrole, to je zarobljeni kontekst slaganja. Reference
Kontekst slaganja (MDN) Z-indeks i konteksti slaganja (web.dev) “Kako stvoriti novi kontekst slaganja sa svojstvom izolacije u CSS-u”, Natalie Pina “Koji je kvragu, z-index??”, Josh Comeau
Dodatno čitanje na SmashingMag
“Upravljanje CSS Z-indeksom u velikim projektima”, Steven Frieson “Ljepljiva zaglavlja i elementi pune visine: lukava kombinacija”, Philip Braunen “Upravljanje Z-indeksom u web aplikaciji koja se temelji na komponentama”, Pavel Pomerantsev “CSS svojstvo Z-indeksa: Sveobuhvatan pogled”, Louis Lazaris