Vertikale und horizontale Zentrierung

Autor: Aykut Şensoy, Datum:

Eines der beliebtesten und häufigsten Fragen bei CSS ist die vertikale und horizontale Zentrierung eines Elements innerhalb eines variablen Containers. In der Vergangenheit war es tatsächlich eine Herausforderung, weswegen es früher auch zahlreiche Artikel zu diesem Thema gab. Nicht wenige Menschen haben sich an CSS-Eigenschaften, wie z.B. vertical-align die Zähne ausgebissen, die zwar zu Zeiten von Tabellenlayouts noch zielführend waren, aber später mit anderen Layout-Konzepten nicht funktioniert haben. Mit den neuen mächtigen Features von CSS sind diese Tage zum Glück vorbei und es gibt heute viele moderne Ansätze, um schnell und einfach zum Ziel zu gelangen. Ich möchte hier auf sämtliche Varianten eingehen, mit denen eine vertikale und horizontale Zentrierung bei variabler Größe möglich ist.

Das ist der initiale Grundaufbau für alle nachfolgenden Beispiele. Alle Beispiele lassen sich für Testzwecke rechts unten am Container greifen und skalieren (außer auf iOS-Geräten, da CSS resize aktuell noch nicht unterstützt wird).

<style>
.container {
  background-color: #ff0;
  height: 300px;
  width: 300px;
}
.container div {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: #80f;
}
</style>

<div class="container">
  <div></div>
</div>

Transform

Bei dieser Variante wird der Content am relativen Container absolut positioniert. Mit den Deklarationen top und left auf 50% wird die obere linke Ecke des Elements mittig positioniert. Damit das Element dann selbst im Container zentriert wird, wird sie vertikal und horizontal negativ um 50% seiner eigenen Dimensionen verschoben, damit der Mittelpunkt des Elements genau in der Mitte des Containers platziert wird.

.container {
  position: relative;
}
.container div {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

Flexbox Variante 1

Bei dieser Variante wird der Content automatisch zu einem flex-item, in dem der Container mit display: flex; zu einem Flex-Container definiert wird. Mit align-items und justify-content wird das flex-item vertikal und horizontal innerhalb des Flex-Containers zentriert. Hierbei handelt es sich heute um die gängigste Methode zur vertikalen und horizontalen Zentrierung.

.container {
  display: flex;
  align-items: center;
  justify-content: center;
}

Flexbox Variante 2

Diese Variante, die ebenfalls wie die vorherige Methode flexbox nutzt, ist pure CSS-Magie. Anstatt üblicherweise align-items und justify-content zu verwenden, wird einfach das flex-item selbst auf margin: auto; gesetzt. Diese Lösung hat schon so manch einen in Erstaunen versetzt. Im Normalfall würde man erwarten, dass das Element sich nur horizontal zentriert, aber hier handelt es sich nicht um ein Block-Element, sondern um ein Flex-Element. Das Flex-Element erweitert automatisch seine Außenabstände, um den zusätzlichen Platz im Flex-Container zu belegen, dadurch wird es nicht nur horizontal, sondern auch vertikal zentriert.

.container {
  display: flex;
}
.container div {
  margin: auto;
}

Grid

Diese Variante verwendet das Grid-Layout-Module und ist damit nicht nur die modernste, sondern auch mit nur 2 Zeilen die kürzeste Methode. Der Content wird hier automatisch zu einem grid-item, in dem der Container mit display: grid; zu einem Grid-Container definiert wird. Die Deklaration place-items sorgt letztendlich für die gewünschte vertikale und horizontale Zentrierung.

Dabei muss man wissen, dass place-items im Grunde nur eine Shortcut-Definition für align-items und justify-items ist, d.h. anstelle von place-items könnte man auch folgendes schreiben: align-items: center; justify-items: center;. Obwohl flexbox und grid viele Deklarationen gemeinsam haben, kann place-items leider nicht für flexbox genutzt werden, da flexbox zwar align-items kennt, aber justify-items von flexbox nicht unterstützt wird.

Diese Variante hat übrigens noch ein besonderes Verhalten. Wenn das Grid-Layout aus mehreren Grid-Zellen besteht, dann wird die Zentrierung auf sämtliche Grid-Zellen angewendet.

.container {
  display: grid;
  place-items: center;
}