CSS/Tutorials/Ausrichtung/Inhalte zentrieren

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

In diesem Artikel werden mehrere Methoden vorgestellt, wie Sie Inhalte horizontal und vertikal zentrieren. Dies soll nur mittels CSS ohne zusätzliches oder verwirrendes Markup in gängige Layouts übernommen werden können. Der zu zentrierende Bereich soll sich bei einer Anzeigebereichsänderung automatisch an den verfügbaren Viewport anpassen.

Beachten Sie: Oft werden aus Designgründen zentrierte Inhalte gewählt. Wenn man etwas mittig platziert, wirkt das Ganze natürlich anders als eine Seite, die an der linken oder rechten Seite klebt. Leider ist genau das aber das Problem des Konzepts: Damit ein zentriertes Layout noch etwas hermacht, muss genügend freie Fläche (Weißraum) vorhanden sein. Sie haben aber keinen Einfluss auf die Viewportgröße Ihrer Benutzer, sodass gutes und responsives Webdesign für alle Arten von Endgeräten und nicht nur für die von Ihnen während der Entwicklung verwendete Bildschirmauflösung optimiert werden sollte.
Hinweis:
Klassennamen sollten nach ihrer Funktion (z.B. „Hinweis“) benannt werden und nicht nach den Formatierungen, die sie beinhalten. So stellen sie sicher, dass die Klasse auch nach einer Überarbeitung der Gestaltung noch nachvollziehbar den Bestandteilen eines Dokuments zugeordnet werden kann.
Zur Vereinfachung werden hier trotzdem die Klassen zentriert und inhalte-werden-vertikal-zentriert verwendet.

Flexbox oder Grid-Layout

Die einfachste Umsetzung gelingt durch Anwenden des Flexbox- oder Grid-Layouts. Mit den Eigenschaften justify-content und align-items können Sie die Inhalte nach Wunsch vertikal und horizontal zentrieren.

Hauptartikel: CSS/Tutorials/Flexbox

Zentrieren mit Flexbox ansehen …
#inhalte-werden-zentriert {
  display: flex;
  align-items: center;
  justify-content: center;
}

In diesem Beispiel erhält das Elternelement des zu zentrierenden Inhalts mit display:flex flexible Layouts ohne feste Größenangaben.
Mit align-items werden Kindelemente zentriert. Wie Sie im unteren main-Element sehen, funktioniert dies auch mit mehreren Kindelementen. Bei kleineren Viewports passt sich der Inhalt an die verfügbare Breite an.

align-content

Seit April 2024 ist in allen großen Browsern eine Erweiterung des CSS Alignment Level 3 Moduls umgesetzt: align-content für Blockelemente und mehrspaltige Elemente. Damit können Sie den Textinhalt eines Blockelements nun ganz einfach vertikal zentrieren oder auch unten ausrichten, ohne dafür extra ein anderes Layoutmodell einrichten zu müssen.

Vertikal zentrieren mit align-content ansehen …
nav ul {
    display: flex;
}
nav a {
    display: block;
    height: 100%;
    text-align: center;
    align-content: center;
}
<nav>
  <ul>
    <li><a href="#">selfhtml<br>Die Energie des Verstehens</a></li>
    <li><a href="#">Forum</a></li>
  </ul>
</nav>

Die Navigationsleiste im Beispiel verwendet Links, die mit display:block und height:100% auf volle Höhe der <li>-Elemente gebracht werden. Ihr Inhalt wird traditionell mit text-align horizontal und neu mit align-content vertikal ausgerichtet.

ältere Varianten

Beachten Sie: Verzichten Sie weitestgehend auf die nachfolgend dargestellten Methoden, da Sie mit ihnen ungewollt feste Größen für eine bestimmte Auflösung festlegen, die bei kleineren Viewports oft anders als beabsichtigt aussehen.

horizontale Zentrierung

margin: auto

Ein gängige Variante Blockelemente zu zentrieren, ist das Setzen des linken und rechten Außenabstands auf den Wert auto:

Beispiel
#zentriert {
  margin-left: auto;
  margin-right: auto;
}

Dies funktioniert aber nur, wenn die Breite (width) des betreffenden Elements bekannt und entsprechend festgelegt ist. Ansonsten nimmt ein Block-Element definitionsgemäß immer die volle zur Verfügung stehende Breite ein, ist also schon so „zentriert“ wie überhaupt möglich.

Allgemein sieht das zu zentrierende Element nur dann auch optisch zentriert aus, wenn der Inhalt gut in die vorgegebene Breite hineinpasst. Ist das Element größer als die vorgegebene Breite, dann ragt es rechts hinaus; ist es jedoch kleiner, wird es an den linken Rand der vorgegebenen Breite gerückt:

Zentrieren durch gleichen Außenabstand (margin) ansehen …
.zentriert {
  margin-left: auto;
  margin-right: auto;
  border: thin solid;
}

div {
  max-width: 30em;
  height: 5em;
  background-color: #dfac20;
}
#p1 { 
  width: 2em; 
}
#p2 { 
  width: 70em; 
}

Die Rahmen um die beiden p-Elemente verdeutlichen das Problem: Die beiden Elemente sind durchaus zentriert, der Inhalt aber leider nicht. Daher ist diese Lösung nur dann praktikabel, wenn die Größe des Inhalts bereits bekannt ist, so wie beim ersten div.


Beachten Sie: Diese Vorgehensweise sollte nur verwendet werden, wenn …
  • die Breite des Inhalts vorher bekannt ist

text-align: center

In einem Fall wie oben mit den beiden p-Elementen könnte man sich gut mit der Eigenschaft text-align statt margin behelfen. Das bedeutet aber auch, dass jede einzelne Textzeile zentriert wird, was nicht immer erwünscht ist, z.B. bei Listen. Ein extremes Beispiel:

Hier ist text-align ungeeignet zum Zentrieren ansehen …
.zentriert  {
  text-align: center
}
<h2 class="zentriert">Meine Vorsätze für's neue Jahr:</h2>
<ul class="zentriert">
  <li>mehr rauchen</li>
  <li>mehr trinken</li>
  <li>auch mal nix tun</li>
  <li>und einfach das Leben genießen!</li>
</ul>
 
<h2 class="zentriert">Meine Vorsätze für's neue Jahr: (extended edition)</h2>
<ul class="zentriert">
  <li>mehr rauchen</li>
  <li>mehr trinken</li>
  <li>auch mal nix tun, d.&nbsp;h.
    <ul>
      <li>keinen Sport treiben</li>
       <li>nicht abnehmen</li>
       <li>und keine guten Vorsätze mehr fassen</li>
    </ul>
  </li>
  <li>und einfach das Leben genießen!</li>
</ul>

Spätestens die verschachtelte Liste am Schluss ist zentriert gänzlich inakzeptabel, da die vormals logischen Einrückungen verschwinden.

Um so etwas mit CSS horizontal zu zentrieren, ohne bereits vorher die Breite der Liste zu kennen, muss man leider die HTML-Datei etwas verändern:

Zentrieren mit display: table

Zentrieren mit zwei DIVs und display:table ansehen …
.inhalte-werden-zentriert {
  display: table;
  margin-left: auto;
  margin-right: auto;	
}

.zentriert  {
  display: table-cell; 
}

Das div1 bildet sozusagen eine Layout-Tabelle mit einem Kindelement (div2), das durch display: table-cell zu einer Zelle wird, welche genau die nötige Breite hat, um den Inhalt (die Liste ul) aufzunehmen. Indem die Außenabstände der Tabelle auf auto gesetzt werden, wird die Tabelle horizontal zentriert. Der Vorteil gegenüber den Layout-Tabellen früherer Jahre? Nun ja, Sie haben zumindest keine semantisch eigentlich falschen Elemente in Ihrem HTML, sondern „nur“ zwei semantisch bedeutungslose, neutrale divs. Entscheiden Sie selbst!

vertikale Zentrierung

Zentrieren mit line-height

Sie können Text in einem Container vertikal zentrieren, wenn Sie die Zeilenhöhe entsprechend einstellen.

vertikale Zentrierung mit line-height
.inhalte-werden-vertikal-zentriert {
  height: 200px;
  line-height: 200px;
}

div img {
  float:left;
}

Elemente mit der Klasse inhalte-werden-vertikal-zentriert erhalten eine feste Höhe und eine gleich große Linienhöhe mit der CSS-Eigenschaft line-height.}}

Beispiel
<div class="inhalte-werden-vertikal-zentriert>
  <img src.beispiel.jpg alt="">
  Erklärungstext
</div>

Das Bild wird links neben dem Erklärungstext dargestellt. Dieser wird vertikal zentriert.


Beachten Sie: Diese Vorgehensweise sollte aus folgenden Gründen nicht verwendet werden:
  • Der Text ist evtl. länger als eine Zeile und wird dann durch die große Zeilenhöhe nicht mehr dargestellt.
  • Sie können niemals sicherstellen, dass Ihr Text in einer Zeile bleibt, wenn er länger wird oder sich der Viewport verkleinert (außer bei einsilbigen Buttonbeschriftungen wie „Los!“).
  • Auch die Höhe des Bildes muss vorher bekannt sein. Bei einer Änderung der Bildabmessung müssen auch die Werte im CSS geändert werden.

Alternative mit display:table-cell

vertikale Zentrierung
.inhalte-werden-vertikal-zentriert {
  height: 200px;
  display: table-cell;
  vertical-align: middle 
}

div img, 
div p  {
  display: inline-block;
}

Mittels display:table-cell verhalten sich die Kindelemente wie Tabellenzellen.

Damit Sie nebeneinander dargestellt werden, erhalten sie display: inline-block.

Beispiel
<div class="inhalte-werden-vertikal-zentriert">
  <img src.beispiel.jpg alt="">
  <p>Erklärungstext</p>
</div>
Beachten Sie: Wenn Sie display:table-cell verwenden wollen, dürfen Sie das Element nicht mit float positionieren!

Vertikal zentrieren mit margin: auto

Wenn Sie dem Element eine feste Höhe geben und es absolut positionieren, können Sie es auch mit margin: auto; zentrieren. [1]

absolute vertikale Zentrierung ansehen …
.absolut-zentriert {
  margin: auto;
  position: absolute;
  top: 0; 
  left: 0; 
  bottom: 0; 
  right: 0;
}

Das gelbe Rechteck wird im Viewport absolut positioniert und dann zentriert.


Beachten Sie: Diese Vorgehensweise sollte aus folgenden Gründen nicht verwendet werden:
  • Wenn Sie die Größe Ihres Browserfensters verändern, sehen Sie, dass sich das gelbe Rechteck zwar immer mittig positioniert, bei kleineren Viewports aber den header überdeckt.

Vertikal und horizontal zentrierte Inhalte

Beispiel ansehen …
html, body { 
  height: 100%; 
  margin: 0;
}

#top {
  float: left; 
  width: 1px; height: 50%;
  margin-bottom: -12em;
}

#container {
  clear: left;
  margin: 0 auto;
  width: 32em; height: 24em;
  background-color: #E0FFE0;
}

Zunächst werden die beiden Elemente html und body auf eine Höhe von 100% gebracht. Um den daraus resultierenden vertikalen Scrollbalken zu eliminieren, werden die Elemente noch von Außenabständen befreit.

Das zuvor angesprochene Element mit der ID top bekommt nun 50% Höhe und 1 Pixel Breite zugewiesen, das untere Ende des Elements befindet sich somit immer exakt in der vertikalen Mitte des Anzeigebereichs. Damit das nachfolgende Element mit der ID container visuell nicht erst ab hier beginnt, wird ein negativer unterer Außenabstand entsprechend der halben Höhe des zu zentrierenden Containers gesetzt. float: left; sorgt schließlich dafür, dass der Container um das top-Element herumfließen kann - aus dem Textfluss genommen wirkt die margin-bottom-Eigenschaft nicht mehr - sobald der Container an der oberen Seite des Anzeigebereichs anstößt. Somit kann das Element nicht mehr unscrollbar aus dem Anzeigebereich verschwinden.

Das Container-Element stellt mittels clear: left; den Textfluss wieder her - ansonsten würde das Element an seinem vorhergehenden Element vorbeifließen und einfach daneben an der oberen Kante des Anzeigebereichs kleben. Über die gewohnte Methode mit margin: 0 auto; wird das Block-Element schließlich horizontal zentriert. Die Breite kann beliebig gewählt werden, die Höhe ebenfalls - allerdings muss der negative Außenabstand des vorhergehenden Elements auf die Hälfte dieses Wertes korrigiert werden.


Beachten Sie: Diese Vorgehensweise sollte aus folgenden Gründen nicht verwendet werden:
  • Dieses Verfahren funktioniert für Elemente mit nicht konstanter Höhe nicht.
  • Auf kleineren Viewports werden Teile des Inhaltsbereichs nicht angezeigt.

Relative oder absolute Größenangaben

Die im Beispiel gewählten em-Werte lassen sich problemlos durch andere Einheiten, etwa ex oder px ersetzen. Eine Angabe in % ist rechnerisch allerdings nicht möglich. Um Prozent-Werte zu verwenden, muss die Höhe des Elements mit der ID top auf die die Hälfte der Resthöhe des body-Elements angepasst und der negative margin-Wert entfernt werden (bei 75% Höhe des Containers muss die Höhe von top 12.5% betragen).

absolute Positionierung

Soll ein Element sowohl horizontal als auch vertikal zentriert werden, bietet sich eine Lösung mit absoluter Positionierung an:

absolute Positionierung
#zentriert {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 30em;
  height: 20em;
  margin-left: -15em;
  margin-top: -10em;
}

Das Element mit der ID "zentriert" wird zunächst so positioniert, dass dessen linke obere Ecke sich genau in der Mitte befindet (top:50%; left:50%;). Anschließend wird es mittels negativer Außenabstände um dessen halbe Breite nach links (margin-left:-15em;) und um dessen halbe Höhe nach oben (margin-top:-10em;) verschoben.

Beachten Sie: Diese Lösung funktioniert augenscheinlich in jedem Browser - sobald aber der Anzeigebereich des Browsers kleiner wird als sein Inhalt, verschwindet der Inhalt nach links oben aus dem Viewport und kann aufgrund des negativen margins nicht mehr durch die Scrollbalken des Browserfensters erreicht werden - dies führt vor allem bei mobilen Geräten mit kleinen Anzeigebereichen zur Unbenutzbarkeit der Seite.

Fazit

Verzichten Sie weitestgehend auf die hier dargestellten Methoden, da Sie mit ihnen ungewollt feste Größen für eine bestimmte Auflösung festlegen, die bei kleineren Viewports oft anders als beabsichtigt aussehen.

Nur die erste Variante mit Flexbox kommt ohne weitere Festlegungen von Breiten und Abständen aus.


Quellen

  1. smashingmagazine.com: Absolute Horizontal And Vertical Centering In CSS vom 09.08.2013

Weblinks