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;
}