Haben Sie jemals z-index: 99999 für ein Element in Ihrem CSS festgelegt und es wird nicht über anderen Elementen angezeigt? Ein so großer Wert sollte das Element optisch leicht über alles andere platzieren, vorausgesetzt, alle verschiedenen Elemente sind entweder auf einen niedrigeren Wert oder gar nicht festgelegt. Eine Webseite wird normalerweise in einem zweidimensionalen Raum dargestellt; Durch die Anwendung spezifischer CSS-Eigenschaften wird jedoch eine imaginäre Z-Achsen-Ebene eingeführt, um Tiefe zu vermitteln. Diese Ebene verläuft senkrecht zum Bildschirm und von ihr aus erkennt der Benutzer die Reihenfolge der übereinander liegenden Elemente. Die Idee hinter der imaginären Z-Achse, der Wahrnehmung gestapelter Elemente durch den Benutzer, besteht darin, dass die CSS-Eigenschaften, die sie erstellen, zu einem sogenannten Stapelkontext kombiniert werden. Wir werden darüber sprechen, wie Elemente auf einer Webseite „gestapelt“ werden, was die Stapelreihenfolge steuert und praktische Ansätze zum „Entstapeln“ von Elementen bei Bedarf. Informationen zum Stapeln von Kontexten Stellen Sie sich Ihre Webseite als Schreibtisch vor. Während Sie HTML-Elemente hinzufügen, legen Sie Zettel nacheinander auf den Schreibtisch. Das zuletzt platzierte Blatt Papier entspricht dem zuletzt hinzugefügten HTML-Element und liegt über allen anderen davor platzierten Papieren. Dies ist der normale Dokumentenfluss, auch für verschachtelte Elemente. Der Schreibtisch selbst stellt den Root-Stacking-Kontext dar, der durch das -Element gebildet wird und alle anderen Ordner enthält. Jetzt kommen bestimmte CSS-Eigenschaften ins Spiel. Eigenschaften wie Position (mit Z-Index), Deckkraft, Transformation und Enthalten verhalten sich wie ein Ordner. Dieser Ordner nimmt ein Element und alle seine untergeordneten Elemente, extrahiert sie aus dem Hauptstapel und gruppiert sie in einem separaten Unterstapel, wodurch ein sogenannter Stapelkontext entsteht. Bei positionierten Elementen geschieht dies, wenn wir einen anderen Z-Index-Wert als auto deklarieren. Für Eigenschaften wie Deckkraft, Transformation und Filter wird der Stapelkontext automatisch erstellt, wenn bestimmte Werte angewendet werden.
Versuchen Sie Folgendes zu verstehen: Sobald sich ein Blatt Papier (d. h. ein untergeordnetes Element) in einem Ordner (d. h. im Stapelkontext des übergeordneten Elements) befindet, kann es diesen Ordner niemals verlassen oder zwischen Papieren in einem anderen Ordner platziert werden. Sein Z-Index ist jetzt nur noch innerhalb seines eigenen Ordners relevant.
In der Abbildung unten befindet sich Papier B nun im Stapelkontext von Ordner B und kann nur zusammen mit anderen Papieren im Ordner bestellt werden.
Stellen Sie sich vor, Sie hätten zwei Ordner auf Ihrem Schreibtisch:
.folder-a { z-index: 1; } .folder-b { z-index: 2; }
Lassen Sie uns das Markup ein wenig aktualisieren. Im Ordner A befindet sich eine spezielle Seite, Z-Index: 9999. Im Ordner B befindet sich eine einfache Seite, Z-Index: 5.
.special-page { z-index: 9999; } .plain-page { z-index: 5; }
Welche Seite ist oben? Es handelt sich um die .plain-Seite im Ordner B. Der Browser ignoriert die untergeordneten Dokumente und stapelt zuerst die beiden Ordner. Es erkennt Ordner B (Z-Index: 2) und platziert ihn über Ordner A (Z-Index: 1), da wir wissen, dass zwei größer als eins ist. In der Zwischenzeit befindet sich die Seite „.special-page“ mit der Einstellung „z-index: 9999“ am Ende des Stapels, obwohl ihr Z-Index auf den höchstmöglichen Wert eingestellt ist. Stapelkontexte können auch verschachtelt werden (Ordner in Ordnern), wodurch ein „Stammbaum“ entsteht. Es gilt das gleiche Prinzip: Ein Kind kann niemals dem Ordner seiner Eltern entkommen. Nachdem Sie nun verstanden haben, wie sich Stapelkontexte wie Ordner verhalten, die Ebenen gruppieren und neu anordnen, lohnt es sich zu fragen: Warum erstellen bestimmte Eigenschaften – wie Transformation und Deckkraft – neue Stapelkontexte? Hier ist die Sache: Diese Eigenschaften erzeugen aufgrund ihres Aussehens keine Stapelkontexte; Sie tun es aufgrund der Art und Weise, wie der Browser unter der Haube funktioniert. Wenn Sie Transformation, Deckkraft, Filter oder Perspektive anwenden, sagen Sie dem Browser: „Hey, dieses Element könnte sich bewegen, drehen oder verblassen, also seien Sie bereit!“
Wenn Sie diese Eigenschaften verwenden, erstellt der Browser einen neuen Stapelkontext, um das Rendern effizienter zu verwalten. Dadurch kann der Browser Animationen, Transformationen und visuelle Effekte unabhängig verarbeiten, wodurch die Notwendigkeit verringert wird, die Interaktion dieser Elemente mit dem Rest der Seite neu zu berechnen. Stellen Sie sich das so vor, als würde der Browser sagen: „Ich behandle diesen Ordner separat, damit ich nicht jedes Mal, wenn sich darin etwas ändert, den gesamten Schreibtisch neu sortieren muss.“ Aber es gibteine Nebenwirkung. Sobald der Browser ein Element in seine eigene Ebene hebt, muss er alles darin „flachen“ und so einen neuen Stapelkontext erstellen. Es ist, als würde man einen Ordner vom Schreibtisch nehmen, um ihn separat zu verwalten. Alles in diesem Ordner wird gruppiert und der Browser behandelt ihn jetzt als eine Einheit, wenn er entscheidet, was darüber liegt. Auch wenn die Transformations- und Opazitätseigenschaften scheinbar keinen Einfluss auf die Art und Weise haben, wie Elemente visuell gestapelt werden, tun sie dies doch, und zwar zur Leistungsoptimierung. Aus ähnlichen Gründen können auch mehrere andere CSS-Eigenschaften Stapelkontexte erstellen. MDN bietet eine vollständige Liste, wenn Sie tiefer in die Materie eintauchen möchten. Davon gibt es einige, was nur verdeutlicht, wie leicht es ist, versehentlich einen Stapelkontext zu erstellen, ohne es zu wissen. Das Problem des „Entstapelns“. Probleme beim Stapeln können aus vielen Gründen auftreten, einige treten jedoch häufiger auf als andere. Modale Komponenten sind ein klassisches Muster, da sie es erfordern, die Komponente so umzuschalten, dass sie auf einer obersten Ebene über allen anderen Elementen „geöffnet“ wird, und sie dann von der obersten Ebene zu entfernen, wenn sie „geschlossen“ ist. Ich bin mir ziemlich sicher, dass wir alle schon einmal in die Situation geraten sind, in der wir ein Modal öffnen und es aus irgendeinem Grund nicht angezeigt wird. Es liegt nicht daran, dass es nicht ordnungsgemäß geöffnet wurde, sondern dass es in einer unteren Ebene des Stapelkontexts nicht sichtbar ist. Da fragt man sich: „Wie kommt das?“ da du eingestellt hast:
.overlay { Position: fest; /* erstellt den Stapelkontext */ Z-Index: 1; /* platziert das Element auf einer Ebene über allem anderen */ Einschub: 0; Breite: 100 %; Höhe: 100 Vh; Überlauf: versteckt; Hintergrundfarbe: #00000080; }
Das sieht korrekt aus, aber wenn das übergeordnete Element, das den modalen Auslöser enthält, ein untergeordnetes Element innerhalb eines anderen übergeordneten Elements ist, das ebenfalls auf z-index: 1 gesetzt ist, wird das modale Element technisch gesehen in einer vom Hauptordner verdeckten Unterebene platziert. Schauen wir uns dieses spezielle Szenario und einige andere häufige Fallstricke im Stapelkontext an. Ich denke, Sie werden nicht nur sehen, wie leicht es ist, versehentlich Stapelkontexte zu erstellen, sondern auch, wie man sie falsch verwaltet. Außerdem hängt es von der Situation ab, wie Sie in einen verwalteten Zustand zurückkehren. Szenario 1: Das gefangene Modal
Sie können Ihr Modal sofort sehen, das in einer Ebene auf niedriger Ebene eingeschlossen ist, und das übergeordnete Element identifizieren. Browsererweiterungen Intelligente Entwickler haben Erweiterungen entwickelt, die dabei helfen. Tools wie diese Chrome-Erweiterung „CSS Stacking Context Inspector“ fügen Ihren DevTools eine zusätzliche Z-Index-Registerkarte hinzu, um Ihnen Informationen zu Elementen anzuzeigen, die einen Stapelkontext erstellen.
IDE-Erweiterungen Mit einer Erweiterung wie dieser für VS Code, die potenzielle Stapelkontextprobleme direkt in Ihrem Editor hervorhebt, können Sie sogar Probleme während der Entwicklung erkennen.
Entstapeln und die Kontrolle wiedererlangen Nachdem wir die Grundursache identifiziert haben, besteht der nächste Schritt darin, sie zu beheben. Es gibt verschiedene Ansätze, mit denen Sie dieses Problem angehen können. Ich werde sie der Reihe nach auflisten. Sie können jedoch auf jeder Ebene jeden auswählen; Niemand kann sich beschweren oder einen anderen behindern. Ändern Sie die HTML-Struktur Dies wird als optimale Lösung angesehen. Damit Sie auf ein Stapelkontextproblem stoßen, müssen Sie einige Elemente an seltsamen Positionen in Ihrem HTML platziert haben. Durch die Neustrukturierung der Seite können Sie das DOM umgestalten und das Stapelkontextproblem beseitigen. Suchen Sie das problematische Element und entfernen Sie es aus dem Trapping-Element im HTML-Markup. Zum Beispiel können wir das erste Szenario „The Trapped Modal“ lösen, indem wir den .modal-Container aus dem Header verschieben und ihn allein im
-Element platzieren.Dieser Inhalt hat einen Z-Index von 2 und deckt das Modal immer noch nicht ab.Kopfzeile
Hauptinhalt
Wenn Sie auf die Schaltfläche „Modal öffnen“ klicken, wird das Modal vor allem anderen positioniert, wie es sein soll. Siehe das Pen-Szenario 1: The Trapped Modal (Solution) [forked] von Shoyombo Gabriel Ayomide. Passen Sie die anÜbergeordneter Stapelkontext in CSS Was ist, wenn es sich bei dem Element um eines handelt, das Sie nicht verschieben können, ohne das Layout zu zerstören? Es ist besser, das Problem anzugehen: Die Eltern legen den Kontext fest. Suchen Sie die CSS-Eigenschaft (oder Eigenschaften), die für das Auslösen des Kontexts verantwortlich ist, und entfernen Sie sie. Wenn es einen Zweck hat und nicht entfernt werden kann, geben Sie dem übergeordneten Element einen höheren Z-Index-Wert als seinen Geschwisterelementen, um den gesamten Container anzuheben. Bei einem höheren Z-Index-Wert bewegt sich der übergeordnete Container nach oben und seine untergeordneten Container erscheinen näher am Benutzer. Basierend auf dem, was wir im Szenario „The Submerged Dropdown“ gelernt haben, können wir das Dropdown-Menü nicht aus der Navigationsleiste verschieben; es würde keinen Sinn ergeben. Wir können jedoch den Z-Index-Wert des .navbar-Containers so erhöhen, dass er größer ist als der Z-Index-Wert des .content-Elements. .navbar { Hintergrund: #333; /* Z-Index: 1; */ Z-Index: 3; Position: relativ; }
Mit dieser Änderung erscheint das .dropdown-Menü nun problemlos vor dem Inhalt.
Siehe das Pen-Szenario 2: The Submerged Dropdown (Lösung) [forked] von Shoyombo Gabriel Ayomide.
Probieren Sie Portale aus, wenn Sie ein Framework verwenden
In Frameworks wie React oder Vue ist ein Portal eine Funktion, mit der Sie eine Komponente außerhalb ihrer normalen übergeordneten Hierarchie im DOM rendern können. Portale sind wie ein Teleportationsgerät für Ihre Komponenten. Mit ihnen können Sie den HTML-Code einer Komponente an einer beliebigen Stelle im Dokument rendern (normalerweise direkt in document.body), während die logische Verbindung zu ihrem ursprünglichen übergeordneten Element für Requisiten, Status und Ereignisse erhalten bleibt. Dies ist perfekt, um Stacking-Kontextfallen zu entkommen, da die gerenderte Ausgabe buchstäblich außerhalb des problematischen übergeordneten Containers erscheint.
ReactDOM.createPortal(
Dadurch wird sichergestellt, dass Ihr Dropdown-Inhalt nicht hinter seinem übergeordneten Element verborgen ist, selbst wenn das übergeordnete Element „overflow:hidden“ oder einen niedrigeren Z-Index aufweist. In dem Szenario „Der abgeschnittene Tooltip“, das wir uns zuvor angesehen haben, habe ich ein Portal verwendet, um den Tooltip vor dem Overflow: Hidden-Clip zu retten, indem ich ihn im Dokumentkörper platziert und über dem Auslöser im Container positioniert habe. Siehe das Pen-Szenario 3: The Clipped Tooltip (Lösung) [forked] von Shoyombo Gabriel Ayomide. Einführung des Stacking-Kontexts ohne Nebenwirkungen Alle im vorherigen Abschnitt erläuterten Ansätze zielen darauf ab, Elemente aus problematischen Stapelkontexten zu „entstapeln“. Es gibt jedoch Situationen, in denen Sie tatsächlich einen Stapelkontext erstellen müssen oder möchten. Das Erstellen eines neuen Stapelkontexts ist einfach, aber alle Ansätze haben einen Nebeneffekt. Das heißt, außer bei der Verwendung von Isolation: isolieren. Bei der Anwendung auf ein Element wird der Stapelkontext der untergeordneten Elemente dieses Elements relativ zu jedem untergeordneten Element und innerhalb dieses Kontexts bestimmt und nicht durch Elemente außerhalb davon beeinflusst. Ein klassisches Beispiel ist die Zuweisung eines negativen Werts an dieses Element, beispielsweise z-index: -1. Stellen Sie sich vor, Sie haben eine .card-Komponente. Sie möchten eine dekorative Form hinzufügen, die hinter dem Kartentext, aber über dem Kartenhintergrund liegt. Ohne einen Stapelkontext auf der Karte sendet z-index: -1 die Form an das Ende des Stammstapelkontexts (die gesamte Seite). Dadurch verschwindet es hinter dem weißen Hintergrund der .card: Siehe den Pen Negative Z-Index (Problem) [forked] von Shoyombo Gabriel Ayomide. Um dieses Problem zu lösen, deklarieren wir „isolation: Isolate“ auf der übergeordneten .card: Siehe den Pen Negative Z-Index (Lösung) [gegabelt] von Shoyombo Gabriel Ayomide. Jetzt wird das .card-Element selbst zu einem Stapelkontext. Wenn sein untergeordnetes Element – die dekorative Form, die auf dem :before-Pseudoelement erstellt wurde – den Z-Index: -1 hat, wird es ganz unten im Stapelkontext des übergeordneten Elements platziert. Es sitzt perfekt hinter dem Text und über dem Hintergrund der Karte, wie beabsichtigt. Fazit Denken Sie daran: Wenn Ihr Z-Index das nächste Mal außer Kontrolle zu geraten scheint, handelt es sich um einen gefangenen Stapelkontext. Referenzen
Stapelkontext (MDN) Z-Index und Stapelkontexte (web.dev) „So erstellen Sie einen neuen Stapelkontext mit der Isolationseigenschaft in CSS“, Natalie Pina „Was zum Teufel, Z-Index??“, Josh Comeau
Weiterführende Literatur zu SmashingMag
„Verwaltung des CSS-Z-Index in großen Projekten“, Steven Frieson „Sticky Header und Full-Height-Elemente: Eine knifflige Kombination“, Philip Braunen „Verwaltung des Z-Index in einer komponentenbasierten Webanwendung“, Pavel Pomerantsev „Die CSS-Eigenschaft Z-Index: Ein umfassender Blick“, Louis Lazaris