Ați setat vreodată z-index: 99999 pe un element din CSS-ul dvs. și nu iese peste alte elemente? O valoare atât de mare ar trebui să plaseze cu ușurință acel element din punct de vedere vizual peste orice altceva, presupunând că toate elementele diferite sunt setate fie la o valoare mai mică, fie nu sunt setate deloc. O pagină web este de obicei reprezentată într-un spațiu bidimensional; cu toate acestea, prin aplicarea proprietăților CSS specifice, este introdus un plan imaginar al axei z pentru a transmite adâncimea. Acest plan este perpendicular pe ecran, iar din el, utilizatorul percepe ordinea elementelor, unul peste altul. Ideea din spatele axei z imaginare, percepția utilizatorului asupra elementelor stivuite, este că proprietățile CSS care o creează se combină pentru a forma ceea ce numim context de stivuire. Vom vorbi despre modul în care elementele sunt „stivuite” pe o pagină web, despre ce controlează ordinea de stivuire și despre abordări practice pentru „demontarea” elementelor atunci când este necesar. Despre stivuirea contextelor Imaginează-ți pagina web ca pe un birou. Pe măsură ce adăugați elemente HTML, așezați bucăți de hârtie, una după alta, pe birou. Ultima bucată de hârtie plasată este echivalentă cu cel mai recent element HTML adăugat și se află deasupra tuturor celorlalte lucrări plasate înaintea acesteia. Acesta este fluxul normal de documente, chiar și pentru elementele imbricate. Desk-ul în sine reprezintă contextul de stivuire rădăcină, format din elementul , care conține toate celelalte foldere. Acum, anumite proprietăți CSS intră în joc. Proprietăți precum poziție (cu index z), opacitate, transformare și conținut) acționează ca un folder. Acest folder preia un element și toți copiii săi, le extrage din stiva principală și le grupează într-o sub-stivă separată, creând ceea ce numim context de stivuire. Pentru elementele poziționate, acest lucru se întâmplă atunci când declarăm o valoare z-index, alta decât auto. Pentru proprietăți precum opacitatea, transformarea și filtrul, contextul de stivuire este creat automat atunci când sunt aplicate anumite valori.
Încercați să înțelegeți acest lucru: odată ce o bucată de hârtie (adică un element copil) se află în interiorul unui folder (adică, contextul de stivuire al părintelui), nu poate ieși niciodată din acel dosar sau nu poate fi plasată între hârtii într-un folder diferit. Indexul său z este acum relevant doar în propriul folder.
În ilustrația de mai jos, Hârtia B se află acum în contextul de stivuire al Folder B și poate fi comandată numai cu alte hârtii din folder.
Imaginează-ți, dacă vrei, că ai două dosare pe birou:
.folder-a { z-index: 1; } .folder-b { z-index: 2; }
Să actualizăm puțin marcajul. Inside Folder A este o pagină specială, z-index: 9999. Inside Folder B este o pagină simplă, z-index: 5.
.special-page { z-index: 9999; } .plain-page { z-index: 5; }
Care pagină este în partea de sus? Este .plain-page din Folder B. Browserul ignoră documentele copil și stivuiește mai întâi cele două foldere. Vede folderul B (z-index: 2) și îl plasează deasupra folderului A (z-index: 1) pentru că știm că doi este mai mare decât unul. Între timp, pagina .special-page setată la z-index: 9999 se află în partea de jos a stivei, chiar dacă z-index-ul său este setat la cea mai mare valoare posibilă. Contextele de stivuire pot fi, de asemenea, imbricate (dosare în foldere), creând un „arborele genealogic”. Același principiu se aplică: un copil nu poate scăpa niciodată din dosarul părinților săi. Acum că înțelegeți cum se comportă contextele de stivuire ca dosare care grupează și reordonează straturile, merită să vă întrebați: de ce anumite proprietăți, cum ar fi transformarea și opacitatea, creează noi contexte de stivuire? Iată chestia: aceste proprietăți nu creează contexte de stivuire din cauza modului în care arată; o fac din cauza modului în care browserul funcționează sub capotă. Când aplicați transformare, opacitate, filtru sau perspectivă, îi spuneți browserului: „Hei, acest element s-ar putea să se miște, să se rotească sau să se estompeze, așa că fiți gata!”
Când utilizați aceste proprietăți, browserul creează un nou context de stivuire pentru a gestiona randarea mai eficient. Acest lucru permite browserului să gestioneze animațiile, transformările și efectele vizuale în mod independent, reducând nevoia de a recalcula modul în care aceste elemente interacționează cu restul paginii. Gândiți-vă la asta ca browser-ul care spune: „Voi gestiona acest folder separat, astfel încât să nu trebuie să remaniez întregul birou de fiecare dată când se schimbă ceva în interiorul lui”. Dar existăun efect secundar. Odată ce browser-ul ridică un element în propriul strat, trebuie să „platească” totul în el, creând un nou context de stivuire. Este ca și cum ai lua un dosar de pe birou pentru a-l gestiona separat; totul din acel folder este grupat, iar browserul îl tratează acum ca o singură unitate atunci când decide ce se află peste ce. Deci, chiar dacă proprietățile de transformare și opacitate ar putea să nu pară să afecteze modul în care elementele se stivuiesc vizual, o fac și este pentru optimizarea performanței. Câteva alte proprietăți CSS pot crea, de asemenea, contexte de stivuire din motive similare. MDN oferă o listă completă dacă doriți să săpați mai adânc. Există destul de multe, ceea ce ilustrează doar cât de ușor este să creezi din neatenție un context de stivuire fără să știi. Problema de „demontare”. Problemele de stivuire pot apărea din mai multe motive, dar unele sunt mai frecvente decât altele. Componentele modale sunt un model clasic, deoarece necesită comutarea componentei pentru a „deschide” pe un strat superior deasupra tuturor celorlalte elemente, apoi îndepărtarea acesteia din stratul superior atunci când este „închis”. Sunt destul de încrezător că toți ne-am confruntat într-o situație în care deschidem un modal și, indiferent de motiv, acesta nu apare. Nu este că nu s-a deschis corect, ci că nu este vizibil într-un strat inferior al contextului de stivuire. Acest lucru vă face să vă întrebați „cum se face?” din moment ce ai setat:
.overlay { poziție: fixă; /* creează contextul de stivuire */ indicele z: 1; /* pune elementul pe un strat deasupra tuturor celorlalte */ inserare: 0; latime: 100%; inaltime: 100vh; preaplin: ascuns; culoare de fundal: #00000080; }
Acest lucru pare corect, dar dacă elementul părinte care conține declanșatorul modal este un element copil dintr-un alt element părinte care este, de asemenea, setat la z-index: 1, asta plasează, din punct de vedere tehnic, modalul într-un substrat ascuns de folderul principal. Să ne uităm la acel scenariu specific și la câteva alte capcane comune în contextul de stivuire. Cred că veți vedea nu numai cât de ușor este să creați din neatenție contexte de stivuire, ci și cum să le gestionați greșit. De asemenea, modul în care reveniți la o stare gestionată depinde de situație. Scenariul 1: Modalul prins
Puteți vedea imediat modulul prins într-un strat de nivel scăzut și puteți identifica părintele. Extensii de browser Dezvoltatorii inteligenți au construit extensii pentru a ajuta. Instrumente precum această extensie Chrome „CSS Stacking Context Inspector” adaugă o filă z-index suplimentară la DevTools pentru a vă afișa informații despre elementele care creează un context de stivuire.
Extensii IDE Puteți chiar să identificați probleme în timpul dezvoltării cu o extensie ca aceasta pentru VS Code, care evidențiază potențialele probleme de context de stivuire direct în editorul dvs.
Demontare și recâștigarea controlului După ce am identificat cauza principală, următorul pas este să o rezolvăm. Există mai multe abordări pe care le puteți lua pentru a rezolva această problemă și le voi enumera în ordine. Totuși, poți alege pe oricine la orice nivel; nimeni nu se poate plânge sau împiedica pe altul. Schimbați structura HTML Aceasta este considerată soluția optimă. Pentru ca tu să te confrunți cu o problemă de context de stivuire, trebuie să fi plasat unele elemente în poziții amuzante în HTML. Restructurarea paginii vă va ajuta să remodelați DOM și să eliminați problema contextului de stivuire. Găsiți elementul problematic și eliminați-l din elementul de captare din marcajul HTML. De exemplu, putem rezolva primul scenariu, „The Trapped Modal”, mutând .modal-container din antet și plasându-l singur în elementul
.Acest conținut are un index z de 2 și tot nu va acoperi modulul.Antet
Conținut principal
Când faceți clic pe butonul „Deschideți modal”, modulul este poziționat în fața tuturor celorlalte așa cum ar trebui să fie. Vezi Scenariul 1 al stiloului: The Trapped Modal (Solution) [forked] de Shoyombo Gabriel Ayomide. AjustațiContextul de stivuire a părinților în CSS Ce se întâmplă dacă elementul este unul pe care nu îl poți muta fără a rupe aspectul? Este mai bine să abordăm problema: părintele stabilește contextul. Găsiți proprietatea (sau proprietățile) CSS responsabile pentru declanșarea contextului și eliminați-o. Dacă are un scop și nu poate fi îndepărtat, dați părintelui o valoare mai mare a indicelui z decât elementele sale frate pentru a ridica întregul container. Cu o valoare mai mare a indicelui z, containerul părinte se mută în partea de sus, iar copiii săi apar mai aproape de utilizator. Pe baza a ceea ce am învățat în scenariul „The Submerged Dropdown”, nu putem muta meniul dropdown din bara de navigare; nu ar avea sens. Cu toate acestea, putem crește valoarea z-index a containerului .navbar pentru a fi mai mare decât valoarea z-index a elementului .content. .navbar { fundal: #333; /* indicele z: 1; */ indicele z: 3; poziție: relativă; }
Odată cu această modificare, meniul .dropdown apare acum în fața conținutului fără nicio problemă.
Vezi Scenariul Pen 2: The Submerged Dropdown (Soluție) [furcată] de Shoyombo Gabriel Ayomide.
Încercați portaluri, dacă utilizați un cadru
În cadre precum React sau Vue, un portal este o caracteristică care vă permite să redați o componentă în afara ierarhiei sale părinte normale în DOM. Portalurile sunt ca un dispozitiv de teleportare pentru componentele dumneavoastră. Vă permit să redați HTML-ul unei componente oriunde în document (de obicei chiar în document.body), menținând-o conectat logic la părintele original pentru elemente de recuzită, stare și evenimente. Acest lucru este perfect pentru a scăpa de capcanele de context de stivuire, deoarece rezultatul redat apare literalmente în afara containerului părinte problematic.
ReactDOM.createPortal(
Acest lucru vă asigură că conținutul dvs. derulant nu este ascuns în spatele părintelui său, chiar dacă părintele are depășire: ascuns sau un index z mai mic. În scenariul „Spinul cu instrumente tăiat” pe care l-am analizat mai devreme, am folosit un portal pentru a salva balonul cu instrumente de la depășire: clip ascuns, plasându-l în corpul documentului și poziționându-l deasupra declanșatorului în interiorul containerului. Vedeți Scenariul 3 al stiloului: The Clipped Tooltip (Soluție) [forked] de Shoyombo Gabriel Ayomide. Introducerea contextului de stivuire fără efecte secundare Toate abordările explicate în secțiunea anterioară au ca scop „demontarea” elementelor din contexte de stivuire problematice, dar există unele situații în care veți avea nevoie sau doriți să creați un context de stivuire. Crearea unui nou context de stivuire este ușoară, dar toate abordările vin cu un efect secundar. Adică, cu excepția utilizării izolării: izolare. Când se aplică unui element, contextul de stivuire al copiilor acelui element este determinat în raport cu fiecare copil și în contextul respectiv, mai degrabă decât să fie influențat de elementele din afara acestuia. Un exemplu clasic este atribuirea acelui element a unei valori negative, cum ar fi indexul z: -1. Imaginați-vă că aveți o componentă .card. Doriți să adăugați o formă decorativă care se află în spatele textului cardului, dar deasupra fundalului cardului. Fără un context de stivuire pe card, z-index: -1 trimite forma în partea de jos a contextului de stivuire rădăcină (întreaga pagină). Acest lucru îl face să dispară în spatele fundalului alb al cardului: Vezi indicele z negativ al stiloului (problema) [furcat] de Shoyombo Gabriel Ayomide. Pentru a rezolva acest lucru, declarăm izolare: izolare pe cardul părinte: Vezi indicele z negativ al stiloului (soluție) [furcat] de Shoyombo Gabriel Ayomide. Acum, elementul .card în sine devine un context de stivuire. Când elementul său copil - forma decorativă creată pe pseudo-elementul :before - are z-index: -1, acesta merge chiar în partea de jos a contextului de stivuire al părintelui. Se așează perfect în spatele textului și deasupra fundalului cardului, așa cum a fost prevăzut. Concluzie Amintiți-vă: data viitoare când indexul dvs. z pare scăpat de sub control, este un context de stivuire prins. Referințe
Context de stivuire (MDN) Z-index și contexte de stivuire (web.dev) „Cum se creează un nou context de stivuire cu proprietatea de izolare în CSS”, Natalie Pina „Ce naiba, indexul z?”, Josh Comeau
Citiri suplimentare despre SmashingMag
„Gestionarea CSS Z-Index în proiecte mari”, Steven Frieson „Antete lipicioase și elemente de înălțime completă: o combinație dificilă”, Philip Braunen „Managing Z-Index într-o aplicație web bazată pe componente”, Pavel Pomerantsev „Proprietatea CSS Z-Index: O privire cuprinzătoare”, Louis Lazaris