Archiv:

Latest photoblog

photoblog

Blog » Vertikal zentrierte Seiten mit CSS

Vertikal zentrierte Seiten mit CSS

Ebenfalls ein Unding aus »vergangenen Zeiten mit Tabellenlayouts«, ist die Angewohnheit eine Seite, unabhängig von ihrer »realen« Höhe, stets vertikal zentriert darstellen zu wollen. Semantisches XHTML schiebt dem jedoch einen Riegel vor, da sich XHTML an XML orientiert und es somit keine absolute Seitenmitte, sondern lediglich noch übergeordnete Elemente gibt. Von daher ist es nahezu unmöglich, eine Seite die in der Höhe variabel ist, mit einem immer gleichen Stylesheet stets vertikal zentriert zu bekommen.

Für Seiten mit fixer Höhe gibt es mittlerweile einige Workarounds. Beispielsweise ist es möglich, die Seite absolut 50% vom oberen Browserrand zu positionieren, und anschließend mittels negativen Margin auf die Seitenmitte zu bringen. Diese Variante ist allerdings nur bedingt geeignet, da die Seite, wenn das Browserfenster zu klein skaliert wird, aus dem oberen Bildrand heraus geschoben wird. Auf eine sehr viel bessere Variante bin ich vor einiger Zeit im Netz gestoßen.

Während man horizontale Zentrierung in der Regel einfach mittels margin: auto auto; erreichen kann, bedarf es bei der vertikalen Zentrierung wie gesagt einiger Nachhilfe. Wem der Code genügt, und auf die Erklärung verzichten kann, schaut sich vorab die kommentierte Demo an.

Wie auch schon in der Erklärung für 100 % Höhe mit festen Footern (Einmal Erdgeschoss bitte), ist es auch hier anfangs von Nöten, 100 % Höhe auf html und body anzuwenden. Ansonsten geht der Browser nicht vom kompletten Viewport aus (also dem im Browserfenster sichtbaren Bereich der Seite).

html, body {
    height: 100%;
    margin: 0; // wichtig für Firefox, IE, Safari & Co
    padding: 0; // wichtig für Opera
}

Der nächste, wohl wichtigste Punkt, ist leider nicht gerade der semantisch korrekteste, aber wie dies in CSS-Layouts oft der Fall ist, geht es nicht wirklich ohne; wir benötigen nun 2 aufeinanderfolgende Elemente, in meinem Beispiel nehme ich 2 divs:

Das div #abstand regelt später den Abstand vom Inhalt zum oberen Browserrand, #inhalt steht logischerweise für den Seiteninhalt.

Da diese Methode wie anfangs erwähnt nur für Seiten mit fixierter Höhe zu gebrauchen ist, sollten wir wissen wie hoch unser Seiteninhalt am Ende sein wird. Von dieser Höhe hängen die Werte ab, die wir später in der Deklaration des #abstand-div benötigen. Ich habe mich in meinem Beispiel komplett auf Angaben in em beschränkt, um zu demonstrieren, dass diese Methode problemlos skalierbar ist.

Wir definieren also eine feste Höhe für den Inhalt (ich habe mich hier für 28em entschieden), als Höhenangabe für den #abstand definieren wir anschließend 50%, also die halbe Höhe des sichtbaren Bereiches im Browserfenster (Viewport). Da sich der Inhalt unter dem Abstand befindet, liegt die obere Kante von #inhalt nun genau bei 50% des Viewports. Durch einen negativen unteren Margin beim #abstand, der exakt die halbe Höhe des #inhalt-divs betragen sollte, wird der Inhalt nun soweit nach oben »gezogen«, dass sich dieser jetzt in der Mitte befindet:

#abstand {
    height: 50%; 
    margin-bottom: -14em; 
    width: 1px;
}
 
#inhalt {
    height: 28em; 
    margin: auto auto; 
}

Schauen wir uns diesen Code in Livedemo 1 an, sehen wir das wir dem gewünschten Endergebnis schon mal sehr nahe sind. Allerdings wird der Inhalt immer noch nach oben aus dem Browserfenster heraus geschoben, sobald wir das Browserfenster kleiner ziehen. Diesen unerwünschten Fehler korrigieren wir nun mit nur zwei kurzen Zeilen im CSS.

Durch die Höhenangabe von 50% in #abstand wird diese jetzt relativ am Browserfenster ausgerichtet. Sollte diese 50%-Höhe nun kleiner werden als die -14em die wir als margin-bottom deklariert haben, wird der Inhalt natürlich höher eingezogen als das Browserfenster hergibt. Um dies zu umgehen, reicht ein simples float: left in #abstand, sowie ein clear: left in #inhalt. Den Elementen wird nun beigebracht, dass #inhalt wie bisher unterhalb von #abstand bleiben, jedoch nicht weiter hochgezogen werden soll wenn #inhalt an die obere Browserkante stößt. Schlussendlich sieht unser komplettes CSS also wie folgt aus:

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
 
#abstand {
    float: left; 
    height: 50%; 
    margin-bottom: -14em; 
    width: 100px;
}
 
#inhalt {
    clear: left; 
    height: 28em; 
}

Nun kann das Browserfenster frei skaliert werden, der Inhalt befindet sich stets in der Mitte, wird jedoch auch bei zu kleinen Browserfenstern nicht mehr aus dem Viewport hinausgeschoben. Anschauen kann man sich dies in der finalen Livedemo 2.

Getestet habe ich dies allerdings nur im Firefox 1.0.7 (Win/Linux), Opera 8 (Win), IE6 (win) und im Konqueror (Linux). Andere Browser und Systeme standen mir leider nicht zur Verfügung.

13 Kommentare zu “Vertikal zentrierte Seiten mit CSS”

  1. Grafik: GravatarSascha Carlin:

    Für den IE reicht margin: auto auto; nicht.
    Um im IE zu zentrieren, brauchts text-align: center; für das Eltern-Element und die Rückgängigmachung dessen für das Kind-Element: text-align: left;

  2. Grafik: GravatarManuel:

    Aber soweit ich weiß nur im Quirksmode, bzw im IE5.x oder? im IE6 klappts bei mir auf jeden Fall auch nur mit margin: auto auto;

    ?

  3. Grafik: GravatarCyberoog, die Insel im Web (Blog):

    CSS von Manuel Bieh

    Ich hab ihn ja schon häufiger erwähnt, ein Weblog gar nicht weit von hier und immer mal wieder interessante, lehrreiche Sachen zu CSS…
    Hier noch zwei Artikel:

    Einmal Erdgeschoss bitte! – Einen Footer bauen
    sowas gibt es auch vom Man in Blue…

  4. Grafik: GravatarBlog@BlueHillTec.Com » Inhalt Vertikal zentrieren mit CSS:

    […] Der Manuel Bieh hat eine Lösung gefunden. […]

  5. Grafik: Gravatarfricca:

    Mit dem nicht mehr auffindbaren Link zu dieser Methode möchte ich gerne aushelfen:
    http://www.xhtmlforum.de/viewtopic.php?p=34786#34786

  6. Grafik: GravatarJuuro:

    Vielen lieben Dank! Das ist jetzt die dritte anleitung zum vertikalen Zentrieren die ich gefunden habe und die erste die auch wirklich funktioniert! :)
    Danke!

  7. Grafik: GravatarDaffi:

    Yeaha, endlich mal ein Tutorial, dass auch wirklich funktioniert. EIn ganz großes Lob und Danke an der Autor!
    (tested width Firefox 1.5.0.7 und IE 6 SP2)

  8. Grafik: GravatarTime:

    Respekt! Schön wie du das beschrieben hast! Eins der am besten, nachzuvollziehenden Tutorials die ich je gelesen habe. Danke!

  9. Grafik: Gravatarben:

    Gute Lösung ohne position:absolute;

    aber leider auch hier wieder nur bei fixer Höhe des zu zentrierenden DIVs. Wie man ein DIV zentrieren kann, dessen Höhe abhängig vom Inhalt ist, wüsste ich noch gerne…

  10. Grafik: GravatarThomas:

    Ben, du kannst die Höhe des divs mit Javascript auslesen und dann denn margin festsetzen. Ist aber nicht so elegant.

    In meinem Fall wird das div mit id „text“ in seinem 400px hohen Elternelement vertikal zentriert. Wenn du ein div ohne Elternelement hast (bzw. es auf der „ganzen Seite“ zentrieren willst), müsstest du einfach den top-margin anders ausrechen (negative halbe Höhe).

    var hoehe = document.getElementById(‚text‘).offsetHeight;
    var marg = ((400 – hoehe) / 2);
    document.getElementById(„text“).style.margin = marg + ‚px‘ + ‚ 0′ + ‚ 0′ + ‚ 0′;

  11. Grafik: GravatarThomas:

    Oder viel eleganter:
    http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

  12. Grafik: GravatarSvenja:

    Vielen Dank, aber musste gerade leider feststellen, dass der Safari damit Probleme hat und u.U. die komplette CSS nicht erkennt. Gibt es dafür nen Workaround?
    Liegt an dem
    html, body {…

  13. Grafik: GravatarHirnsoup:

    Manuel Bieh – Web Development & Consulting…

    Vertical und Horizontal Zentrierte Divs…

Die Trackback-URL lautet