100% Height-Stretching mit "em"
Pongo
- css
0 Matthias Apsel
0 Pongo
0 Matthias Apsel
0 Pongo
Hallo allerseits,
ich arbeite an einem Layout mit 3 horizontalen Spalten. Mein Ziel war es, das Layout schön skalierbar, bzw. barrierefrei, zu bauen. Mit anderen Worten: Ich möchte relative Größen benutzen (em), sodass das Layout automatisch größer wird, wenn man in seinem Browser die Schriftgröße umstellt. Und bis auf eine winzige Kleinigkeit funktioniert es bisher auch perfekt. :)
Konkret geht es um ein 3 Reihen-Layout (also horizontale "Spalten"). Ich habe quasi 2 Header und einen Content-Bereich; in etwa so:
+--------------+
| Header 1 |
+--------------+
| Header 2 |
+--------------+
| Content | |
| |S| <--- Die S-Spalte signalisiert einen Scrollbalken :)
| | |
+--------------+
In meinem body ist die font-size auf 62,5% gestellt, damit bei Standard-Einstellung der Browser für die Schriftgröße (16px) 1em = 10px gilt, was das layouten mit "em" recht einfach macht (die Technik kennen hier sicher einige).
Jedenfalls sind bei den Inhalten der ersten beiden Reihen alle CSS-Eigenschaften, welche die Höhe betreffen, mittels "em" angegeben, also vertikale Paddings, Border etc. Diese ganzen "vertikalen Werte" werden aufaddiert und bestimmen die absolute top-Position der dritten Reihe. Diese ist absolut positioniert, damit sie den gesamten restlichen Raum des Dokuments einnimmt, also 100% Höhe des Dokumentes minus die Höhe der beiden Header. Diese dritte Content-Reihe bekommt dann später ein "overflow:auto" verpasst, sodass bei zu langen Inhalten schließlich Scrollbalken erscheinen.
Und dadurch, dass 0.1em = 1px gilt, lässt sich das so auch alles schön pixelgenau ausrichten, was hervorragend funktioniert!
Ein Problem habe ich nur, wenn ich in meinem Browser tatsächlich mal die Schriftgröße erhöhe oder die Zoom-Funktion des Browsers nutze. Dann bekomme ich eine Lücke zwischen dem 2. Header und der absolut positionierten Content-Reihe.
Ich bin alle Berechnungen meiner relativen Größen x-fach durchgegangen und konnte keinen Fehler finden (Dank Sass bin ich mir seeeehr sicher :). Und ohne Zoom/Schriftgrößenänderung funktioniert es auch tadellos. Ich nehme an, dass der Browser sich hier beim Berechnen der genauen Pixel aus relativen Angaben schlichtweg verrechnet, bzw. Rundungsfehler auftreten.
Da Bilder mehr als tausend Worte sagen, hier mal ein Beispiel:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
height: 100%;
padding: 0;
margin: 0;
font-size: 62.5%; /* 1em = 10px */
}
header {
line-height: 2em;
border-width: 0.1em 0;
border-color: red;
border-style: solid;
background-color: #999;
}
div {
position: absolute;
top: 2.2em; /* 2em + 0.1em * 2 */
bottom: 0;
right: 0;
left: 0;
background-color: #333;
}
</style>
<title>Test</title>
</head>
<body>
<header>Header</header>
<div>Content</div>
</body>
</html>
Öffnet man das Beispiel im Browser, sieht man Header und Content-Box perfekt aneinander positioniert, ohne Lücke, und die Content-Box nimmt den gesamten restlichen body-Bereich in Anspruch.
Wenn ihr jetzt in eurem Browser (getestet Chromium/FireFox) die Schriftgröße erhöht oder die Zoom-Funktion verwendet, werdet ihr feststellen, dass zwischen den Containern plötzlich eine weiße Lücke entsteht.
Der Firefox scheint hier genauer zu rechnen, denn dort muss ich stärker zoomen, bis eine Lücke entsteht.
Jedenfalls möchte ich diesen Effekt verhindern. Hat da jemand eine Idee oder einen Tipp oder gar eine Lösung?
Am einfachsten wäre es natürlich, wenn ich bei der dritten Content-Box auf eine absolute Positionierung verzichten könnte. Dann hätte ich den Fall wie bei den zwei Headern im Beispiel, die aufgrund von relativer Positionierung fließend aneinander "kleben", selbst wenn gezoomt wird.
Aber da habe ich dann keine Idee, wie ich diesen Content-Bereich dazu bringe, die gesamte restliche Fläche des Dokuments einzunehmen. Any ideas? :)
Danke schonmal im Voraus für eure Antworten.
Gruss,
Pongo
Om nah hoo pez nyeetz, Pongo!
Ich sähe die Möglichkeit, das body-Element als 3. Contentbereich zu verwenden.
Matthias
Dann würde aber bei zu langen Inhalten der gesamte body scrollbar sein, was nicht gewollt ist :) Es soll nur der 3. Content-Container scrollbar sein und die Header sollen stets sichtbar sein. Es handelt sich bei dem ganzen nicht um eine Webseite sondern eine Webapp :)
Om nah hoo pez nyeetz, Pongo!
Ich sähe weiters die Möglichkeit, dem Header-Element einen deutlich breiteren unteren Rahmen zu verpassen.
Matthias
Wie genau meinst du das? Wenn ich bei meinem Beispiel die Rahmen bspw. auf 0.5em Breite setze und den Content-Container einen top-Wert von 3em gebe, habe ich das gleiche in grün: Beim Zoomen im Browser entsteht irgendwann eine Lücke. (Gerade getestet mit Chromium :)
Eine Notlösung wäre IMHO dem body die gleiche Hintergrundfarbe zu geben, wie dem Header (bzw. dem 2. Header). Dann entsteht zwar immernoch die Lücke, aber man sieht sie nicht so offensichtlich. Wenn es jedoch anders geht, würde ich die andere Lösung bevorzugen. :)
Om nah hoo pez nyeetz, Pongo!
Eine Notlösung wäre IMHO dem body die gleiche Hintergrundfarbe zu geben, wie dem Header (bzw. dem 2. Header). Dann entsteht zwar immernoch die Lücke, aber man sieht sie nicht so offensichtlich. Wenn es jedoch anders geht, würde ich die andere Lösung bevorzugen. :)
Ich habe in deinem geposteten Bespiel den unteren Border von header 10em breit gemacht und den Abstand so gelassen, also dafür gesorgt, das der border garantiert breiter als der Abstand zwischen content und header ist.
Matthias
Ah, ich verstehe. Also quasi ähnlich zu meiner "Lösung" mit der Hintergrundfarbe (in meiner echten Webapp gibt es nämlich keinen unteren Border :).
Vermutlich geht es anders einfach nicht, als diese Lücke beim Zoomen zu kaschieren (mittels Hintergrundfarbe/Border).
Om nah hoo pez nyeetz, Pongo!
ebenso wäre eine Überlappung der Elemente selbst möglich.
Matthias