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