mitmario.dev

Badge, Overlay und klebende Kopfzeile

CSS Im Browser 3 Min Lesezeit 3 BeispieleLektion 7 von 8

Hier treffen alle Positionsarten zum ersten Mal auf einer Seite aufeinander. Jede für sich kennst du jetzt, und interessant wird es erst dort, wo sie sich auf derselben Seite gegenseitig in die Quere kommen.

Die Teile

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

/* 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: #14532d;
}

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

/* relative ohne Werte: nur Bezugsrahmen. */
.rezept {
  position: relative;
  max-width: 300px;
  margin-bottom: 24px;
  padding: 16px;
  border: 1px solid #d6d3d1;
  border-radius: 8px;
  background-color: #ffffff;
}

/* absolute an zwei benachbarten Seiten: heftet an. */
.etikett {
  position: absolute;
  top: 24px;
  left: 24px;
  z-index: 2;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 13px;
  color: #ffffff;
  background-color: #15803d;
}

.foto {
  position: relative;
  height: 120px;
  border-radius: 4px;
  background-color: #a8a29e;
}

/* absolute an allen vier Seiten: spannt auf. */
.foto-flaeche {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #ffffff;
  background-color: rgb(20 83 45 / 50%);
}

/* fixed: hängt am Ausschnitt, nicht am Dokument. */
.nach-oben {
  position: fixed;
  right: 24px;
  bottom: 24px;
  padding: 8px 16px;
  border-radius: 999px;
  text-decoration: none;
  color: #ffffff;
  background-color: #15803d;
}
  • Die Kopfzeile klebt und braucht dafür top, sonst passiert nichts.
  • Sie braucht außerdem einen z-index, sonst schieben sich die Karten darüber, weil die ebenfalls positioniert sind und später im Dokument stehen.
  • Die Karte ist Bezugsrahmen, damit ihr Etikett eine Ecke findet.
  • Das Etikett heftet an zwei benachbarten Seiten, die Fläche über dem Foto spannt mit inset: 0 auf. Beides sind Muster von position: absolute.
  • Der Zurück-Button ist fixiert und bekommt seinen Platz am body zurück.
  • Die Rezeptliste trägt 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: 4px 8px;
  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;
}

Fehlt der Rahmen an der Karte, sucht der Browser weiter außen. Steht dort einer, den jemand für etwas anderes gesetzt hat, landet das Badge in dessen Ecke. Das sieht dann fast richtig aus.

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. Maßgeblich ist der nächste positionierte Vorfahre. Deshalb hängt das Badge einmal in der Ecke der Liste und einmal dort, wo es hingehört.

Mit dem Ablauf aus Lektion 8.3 sieht das so aus. Am oberen Badge steht position: absolute, an der Karte darum static, an der Liste relative. Der Rahmen ist also die Liste. Beim unteren Paar ist eine Ebene früher Schluss, dort steht schon an der Karte position: relative. Zwei Züge mit dem Zeiger, und die Frage ist beantwortet.

In einem echten Projekt schreibt jemand 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.

position: relative gehört deshalb 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 so lange, wie unter ihr nichts Positioniertes durchscrollt.

Die Karten bekommen aber selbst position: relative, weil sie ein Badge tragen sollen. Ab da 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. Zweimal auto heißt, dass es nichts zu vergleichen gibt.

An dieser Stelle fängt man leicht an, Zahlen zu raten. Ich lege lieber einmal eine kleine Skala fest. Die Kopfzeile bekommt zehn, ein Overlay hundert, Kleinkram innerhalb einer Komponente ein oder zwei. Sind die Komponenten dazu noch isoliert, kollidieren die beiden Bereiche nie.

Die Reihenfolge beim Suchen

Ab hier gilt für jedes Positionierungsproblem derselbe Ablauf. Er setzt den aus Lektion 3.5 fort, und die Reihenfolge spart wirklich Zeit.

  1. Der Bezugsrahmen. Sitzt das Element überhaupt in dem Rahmen, der gemeint ist? Gesucht wird unter den Vorfahren der erste mit einer Position ungleich static. Ist er zu weit außen oder gar nicht da, ist das die Antwort, und der Rest entfällt.
  2. Die Ebenen. Liegt es an der richtigen Stelle, aber unter dem falschen Nachbarn? Dann geht es um z-index und gleich danach um die Frage, ob ein Vorfahre einen Stacking Context aufmacht.
  3. Die Werte. Erst jetzt sind top, right und die Zahlen dran.

Fängst du mit den Zahlen an, verstellst du Werte an einem Element, das an einer völlig anderen Stelle hängt.

In der Aufgabe fehlt einem Stück der Portfolio-Seite noch jede Positionierung.

Zum Mitnehmen

Beim Suchen kommt zuerst der Bezugsrahmen dran, dann die Ebenen und erst zuletzt die Werte. Ein position: relative an einem Container weit außen fängt jedes Badge ein, das darunter keinen näheren Rahmen findet.

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.