Abschnitt 11 · Lektion 2
Zentrieren
“Wie zentriere ich das” ist die meistgestellte CSS-Frage überhaupt, und sie hat fünf richtige Antworten. Diese Lektion stellt sie nebeneinander, damit du dir nicht die falsche merkst.
Vier Wege, die du dauernd brauchst
<p class="titel">1. margin-inline: auto, braucht eine Breite</p>
<div class="feld">
<div class="kasten weg-a">margin-inline</div>
</div>
<p class="titel">2. text-align: center, zentriert den Inhalt</p>
<div class="feld weg-b">
<span>text-align</span>
</div>
<p class="titel">3. Flexbox, zentriert die Kinder in beide Richtungen</p>
<div class="feld hoch weg-c">
<div class="kasten">Flexbox</div>
</div>
<p class="titel">4. Grid mit place-items, dasselbe in zwei Zeilen</p>
<div class="feld hoch weg-d">
<div class="kasten">Grid</div>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
}
.titel {
margin-bottom: 4px;
font-size: 14px;
color: #52525b;
}
.feld {
margin-bottom: 16px;
padding: 8px;
background-color: #e4e4e7;
}
.hoch {
height: 120px;
}
.kasten {
padding: 12px 20px;
font-weight: 700;
color: #ffffff;
background-color: #2563eb;
}
/* Eine Breite ist Pflicht. Ohne sie füllt der Block
die ganze Zeile, und dann gibt es nichts mehr zu
verteilen. Wirkt nur waagerecht. */
.weg-a {
width: 220px;
margin-inline: auto;
}
/* Zentriert den Inline-Inhalt, nicht den Kasten
selbst. Vererbt sich nach unten. */
.weg-b {
text-align: center;
}
.weg-c {
display: flex;
justify-content: center;
align-items: center;
}
.weg-d {
display: grid;
place-items: center;
} margin-inline: auto verteilt den übrigen Platz links und rechts gleichmäßig. Es braucht zwingend eine Breite, sonst füllt der Block die ganze Zeile und es gibt nichts zu verteilen. Und es wirkt nur waagerecht. Das ist der Weg für den zentrierten Inhaltsbereich einer Seite, den du in Lektion 4.3 schon gebaut hast.
text-align: center zentriert den Inline-Inhalt eines Elements: Text, Bilder, Inline-Blöcke. Nicht das Element selbst. Es vererbt sich, was praktisch ist und einen gern überrascht.
Flexbox mit justify-content: center und align-items: center zentriert die Kinder in beide Richtungen. Zwei Zeilen plus display: flex.
Grid mit place-items: center macht dasselbe in einer Zeile plus display: grid. Für “ein Element mittig in einem Kasten” ist das der kürzeste Weg, den CSS zu bieten hat.
Zeig mit dem Inspector der Reihe nach auf die vier Kästen, dann siehst du, wie unterschiedlich die vier Wege dabei vorgehen. Am blauen Kasten des ersten steht margin: 0px 64px: “verteil den übrigen Platz” bleibt nicht als Anweisung stehen, im Streifen steht das Ergebnis der Rechnung. Am zweiten Feld steht text-align: center und sonst nichts. Beim dritten kommen justify-content: center und align-items: center dazu, beim vierten align-items: center und justify-items: center. place-items selbst findest du dort nicht: Kurzschreibweisen stehen im Streifen nie, immer nur das, worin sie zerfallen.
Der Irrtum, den alle einmal haben
<p class="titel">text-align am Elternteil: der Text rückt, der Kasten nicht</p>
<div class="feld text">
<div class="kasten">Ich bin ein Block mit 220px Breite.</div>
</div>
<p class="titel">margin-inline: auto am Kasten: der Kasten rückt</p>
<div class="feld">
<div class="kasten mitte">Ich bin ein Block mit 220px Breite.</div>
</div> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
}
.titel {
margin-bottom: 4px;
font-size: 14px;
color: #52525b;
}
.feld {
margin-bottom: 16px;
padding: 8px;
background-color: #e4e4e7;
}
.kasten {
width: 220px;
padding: 12px;
color: #ffffff;
background-color: #2563eb;
}
/* Der blaue Kasten klebt weiterhin links, nur seine
Zeilen sind mittig. Das ist der häufigste Irrtum
beim Zentrieren. */
.text {
text-align: center;
}
.mitte {
margin-inline: auto;
} text-align: center am Elternteil, und der Kasten klebt trotzdem links. Das ist kein Fehler, das ist genau die Beschreibung: Der Inhalt wird zentriert, nicht der Kasten.
Ein Block nimmt die Breite, die er hat, und text-align sagt nur etwas darüber, wie seine Zeilen darin ausgerichtet sind. Willst du den Block selbst bewegen, brauchst du margin-inline: auto an ihm oder einen Elternteil, der ihn ausrichtet.
Die beiden blauen Kästen sind bis auf ihre Stelle identisch, und der Inspector zeigt das genauer als das Auge. Beide messen 220 × 62, beide haben dieselbe Schrift, dieselbe Farbe, dasselbe Polster. Auseinander gehen zwei Zeilen: oben steht margin: 0px, unten margin: 0px 64px. Und am oberen Kasten steht text-align: center, obwohl in seiner eigenen Regel nichts dergleichen vorkommt. Die Angabe kommt vom Elternteil und wird vererbt. Sie richtet die Zeilen im Kasten aus und lässt den Kasten selbst in Ruhe, und genau das ist der ganze Irrtum.
Merk es dir an der Frage: Zentriere ich das Element oder seinen Inhalt? Aus der Antwort fällt der Weg von allein heraus.
Wenn der Elternteil nicht mitspielt
<div class="feld">
<div class="schild">inset: 0 plus margin: auto</div>
</div>
<p class="hinweis">
Der Elternteil ist hier weder Flex noch Grid, er ist nur
Bezugsrahmen. Das reicht: alle vier Seiten auf null spannen den
verfügbaren Platz auf, und margin: auto verteilt ihn gleichmäßig
in beide Richtungen. Eine Größe muss man dafür kennen, hier sind
es 280 mal 48 Pixel.
</p> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
}
.feld {
position: relative;
height: 160px;
margin-bottom: 16px;
background-color: #e4e4e7;
}
.schild {
position: absolute;
inset: 0;
width: 280px;
height: 48px;
margin: auto;
padding: 12px;
text-align: center;
font-weight: 700;
color: #ffffff;
background-color: #2563eb;
}
.hinweis {
max-width: 56ch;
color: #52525b;
} Der fünfte Weg ist der aus Abschnitt 8: position: absolute, inset: 0 und margin: auto. Alle vier Seiten auf null spannen den verfügbaren Platz auf, und der automatische Außenabstand verteilt ihn gleichmäßig in beide Richtungen.
Am Schild steht im Streifen position: absolute und margin: 56px 42px, und beide Zahlen kannst du nachrechnen: Das Feld ist 160 Pixel hoch, das Schild 48, macht 112 übrig und 56 je Seite. Waagerecht hängt die zweite Zahl an der Breite deiner Spalte; bei 364 Pixeln Feldbreite und 280 Pixeln Schild sind es 42. Zieh an der Trennlinie, dann wandert diese Zahl mit und die 56 bleiben stehen.
Der Weg ist selten die erste Wahl, weil er einen Bezugsrahmen und eine bekannte Größe braucht. Aber er hat einen Vorteil, den die anderen nicht haben: der Elternteil muss nichts tun. Wenn du an das Layout des Elternteils nicht herankommst, etwa weil es aus einer fremden Komponente kommt, ist das der Ausweg.
Und die alte Transform-Lösung, die man in älteren Antworten überall findet:
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
Die funktioniert weiterhin und hat einen echten Vorteil gegenüber der inset-Variante: Sie braucht die Größe des Elements nicht zu kennen. Für die meisten Fälle sind Flexbox und Grid trotzdem kürzer und lesbarer. Merk sie dir als Reserve, nicht als Standard.
Zum Mitnehmen
Wie zentriere ich das ist die meistgestellte CSS-Frage überhaupt, und sie hat fünf richtige Antworten. Sie ersetzen sich nicht gegenseitig: die Frage ist jedes Mal, ob du das Element zentrierst oder seinen Inhalt.
Jetzt du
Basis Konto, kostenlosZu 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.