mitmario.dev

Synthese: Badge, Overlay und klebende Kopfzeile

CSS Im Browser 3 Min Lesezeit 3 BeispieleLektion 7 von 8

Alle fünf Positionsarten treffen in diesem Abschnitt zum ersten Mal auf einer Seite aufeinander. Jede für sich ist erklärt. Interessant wird es dort, wo sie sich gegenseitig in die Quere kommen.

Was hier zusammenkommt

Vier Positionsarten auf einer Seite
body {
  margin: 0;
  padding-bottom: 80px;
  font-family: system-ui, sans-serif;
  background-color: #f4f4f5;
}

/* sticky: klebt oben und behält seinen Platz. */
header {
  position: sticky;
  top: 0;
  z-index: 10;
  padding: 16px 24px;
  font-weight: 700;
  color: #ffffff;
  background-color: #18181b;
}

.projekte {
  isolation: isolate;
  padding: 24px;
}

/* relative ohne Werte: nur Bezugsrahmen. */
.projekt {
  position: relative;
  max-width: 320px;
  margin-bottom: 32px;
  padding: 16px;
  border-radius: 12px;
  background-color: #ffffff;
}

/* absolute an zwei benachbarten Seiten: heftet an. */
.badge {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 14px;
  color: #ffffff;
  background-color: #2563eb;
}

.bild {
  position: relative;
  height: 120px;
  border-radius: 8px;
  background-color: #3f3f46;
}

/* absolute an allen vier Seiten: spannt auf. */
.bild-overlay {
  position: absolute;
  inset: 0;
  padding-top: 48px;
  text-align: center;
  color: #ffffff;
  background-color: rgb(24 24 27 / 40%);
}

/* fixed: hängt am Ausschnitt, nicht am Dokument. */
.nach-oben {
  position: fixed;
  right: 24px;
  bottom: 24px;
  padding: 12px 20px;
  border-radius: 999px;
  text-decoration: none;
  color: #ffffff;
  background-color: #2563eb;
}

Die Kopfzeile klebt (8.5) und braucht dafür top, sonst passiert nichts.

Sie braucht außerdem einen z-index (8.6), sonst schieben sich die Karten darüber, weil die ebenfalls positioniert sind und später im Dokument stehen.

Die Karte ist Bezugsrahmen (8.2), damit ihr Badge eine Ecke findet.

Das Badge heftet an zwei benachbarten Seiten (8.3), das Overlay spannt mit inset: 0 auf. Zwei Muster derselben Eigenschaft.

Der Zurück-Knopf ist fixiert (8.4) und bekommt seinen Platz am body zurück.

Und dazu die Kartenliste mit isolation: isolate, damit die Zahlen im Inneren nie gegen die Kopfzeile antreten müssen.

Der Rahmen an der falschen Stelle

Der Bezugsrahmen an der falschen Stelle
body {
  font-family: system-ui, sans-serif;
}

.liste {
  padding: 24px;
  margin-bottom: 24px;
  background-color: #f4f4f5;
}

.projekt {
  padding: 16px;
  border-radius: 12px;
  background-color: #ffffff;
}

.badge {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 14px;
  color: #ffffff;
  background-color: #2563eb;
}

/* Es zählt der nächste positionierte Vorfahr. Steht der
   eine Ebene zu weit außen, sitzt das Badge in der Ecke
   der Liste statt in der Ecke der Karte. */
.falsch {
  position: relative;
}

.richtig {
  position: relative;
}

Der häufigste Fehler in solchen Aufbauten ist nicht der fehlende Bezugsrahmen, sondern der überzählige.

Beide Karten im Beispiel haben ein Badge mit denselben Werten. Bei der oberen sitzt position: relative an der Liste, bei der unteren an der Karte. Das Badge sucht sich den nächsten positionierten Vorfahren, und deshalb hängt es einmal in der Ecke der Liste und einmal dort, wo es hingehört.

Geh den Ablauf aus 8.3 einmal an diesem Beispiel durch. Zeig auf das obere Badge, dann auf die Karte darum, dann auf die Liste: position: absolute, dann static, dann relative. Der Rahmen ist also die Liste. Beim unteren Paar hörst du eine Ebene früher auf, dort steht schon an der Karte position: relative. Zwei Züge mit dem Zeiger, und die Frage ist beantwortet.

In einem echten Projekt entsteht das so: Jemand schreibt position: relative an einen Container, weil er dort einmal etwas positionieren wollte. Ein halbes Jahr später kommt ein Badge in eine Karte darin, und niemand versteht, warum es eine Ebene zu weit außen landet.

Deshalb die Regel: position: relative gehört so dicht wie möglich an das Element, dem es dienen soll. Nicht an den Wrapper, nicht an die Liste, nicht an main.

Wer über wem liegt

Die Kopfzeile ohne z-index
body {
  margin: 0;
  font-family: system-ui, sans-serif;
  background-color: #f4f4f5;
}

/* Klebt zwar, hat aber keinen z-index. */
header {
  position: sticky;
  top: 0;
  padding: 16px 24px;
  font-weight: 700;
  color: #ffffff;
  background-color: #18181b;
}

/* Auch positioniert, steht später im Dokument und
   gewinnt deshalb gegen die Kopfzeile. */
.projekt {
  position: relative;
  margin: 24px;
  padding: 32px 16px;
  border-radius: 12px;
  background-color: #ffffff;
}

Eine klebende Kopfzeile ohne z-index funktioniert genau so lange, wie unter ihr nichts Positioniertes durchscrollt.

Sobald die Karten selbst position: relative bekommen, weil sie ein Badge tragen sollen, gewinnen sie gegen die Kopfzeile: beide sind positioniert, beide haben keinen z-index, und dann entscheidet die Reihenfolge im Dokument.

Im Streifen steht das an beiden Elementen wörtlich so. An der Kopfzeile position: sticky und z-index: auto, an einer Karte position: relative und ebenfalls z-index: auto. Zwei Mal auto heißt: Es gibt nichts zu vergleichen, und die Reihenfolge im Dokument entscheidet.

Das ist der Moment, in dem viele anfangen, Zahlen zu raten. Die Lösung ist eine kleine Skala, einmal festgelegt: die Kopfzeile bekommt zehn, ein Overlay hundert, Kleinkram innerhalb einer Komponente ein oder zwei. Wenn die Komponenten dazu noch isoliert sind, kollidieren die beiden Bereiche nie.

Die Reihenfolge beim Suchen

Zum Schluss der Ablaufplan, der ab hier für jedes Positionierungsproblem gilt. Er ist die Fortsetzung dessen aus Lektion 3.5, und die Reihenfolge ist keine Empfehlung, sondern spart wirklich Zeit.

Erstens: der Bezugsrahmen. Sitzt das Element überhaupt in dem Rahmen, den du meinst? Geh die Vorfahren durch und such den ersten mit einer Position ungleich static. Ist er zu weit außen oder gar nicht da, hast du die Antwort und brauchst gar nicht weiterzulesen.

Zweitens: der Stapel. Liegt es an der richtigen Stelle, aber unter dem falschen Nachbarn? Dann geht es um z-index, und die zweite Frage lautet, ob ein Vorfahr einen Stacking Context aufmacht.

Drittens: die Werte. Erst jetzt sind top, right und die Zahlen dran.

Wer diese Reihenfolge umdreht und mit den Zahlen anfängt, verstellt Werte an einem Element, das an einer völlig anderen Stelle hängt. Das ist der Nachmittag, den position sich sonst nimmt.

Zum Mitnehmen

Beim Suchen immer in dieser Reihenfolge: erst der Bezugsrahmen, dann der Stapel, dann die Werte. Wer mit den Werten anfängt, ändert Zahlen an einem Element, dessen Problem ganz woanders liegt.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.