CSS Boxmodell Chaos – die Lösung

Eigentlich bin ich ja auf Grund des Boxmodell-Chaos ein Anhänger des Tabellenlayouts.

Aber seit ich mich mit WordPress beschäftige, habe ich mich doch noch einmal intensiv mit dem Boxmodell auseinandergesetzt, ein Tabellenlayout wollte ich WordPress nun doch nicht antun, obwohl es funktionieren würde.

Noch einmal zur Erinnerung:

CSS-Boxmodell: width steht dem Inhalt zur Verfügung, padding, margin und border liegen aussen. Der horizontale Platzbedarf der Box beträgt width + 2xmargin + 2xborder + 2xpadding.

IE-Boxmodell (IE5 und IE6 im Quirks-Modus): Inhalt, padding und border liegen innerhalb von width, margin liegt aussen. Der horizontale Platzbedarf der Box beträgt width + 2xmargin.

Wenn man also padding und border benutzt, wird das in verschiedenen Browsern unterschiedlich angezeigt. Keine gute Voraussetzung, um ein in allen Browsern gleiches Layout zu entwerfen. 

erster Versuch: verschachtelte Layoutboxen ohne padding

Also ganz einfach, habe ich mir gedacht, werde ich also auf padding verzichten. Ich kann ja 2 div-Boxen ineinander schachteln. Die äussere Box bekommt margin und border, die innere nur margin, das ersetzt das padding der äusseren Box. 2-fache Verschachtelung … es gibt schlimmeres. Gesagt – getan.

Meiner äusseren Layout-Box habe ich also margin: 20px, padding: 0 und einen Rahmen von 10px gegeben (zu Testzwecken), width habe ich auf 400px gesetzt und die ganze Box links gefloatet. Die innere Box bekam 20px margin und sonst nix. Die gesamte Konstruktion sollte nun horizontal 400px width + 2×20px(margin aussen) + 2×10px(border aussen) Platz einnehmen, also 460px. Die innere Box passt sich ja der äusseren an, wenn ich ihr kein width zuweise. 

Was denn, margin geht auch nicht ???

Wie gross war mein Erstaunen, als ich in verschiedenen Browsern 3 unterschiedliche Boxen angezeigt bekam !!!

Zuerst einmal hatte ich nicht beachtet, dass das CSS-Boxmodell und das IE-Boxmodell das border unterschiedlich behandeln. Das ergibt schon mal einen Unterschied von 20px (2xborder) zwischen CSS-Boxmodell und IE-Boxmodell. Nur gut, dass ich vorsichtshalber diesen dicken Rahmen gesetzt habe, sonst hätte ich das vielleicht gar nicht gemerkt.

Aber es kommt noch schlimmer. Der IE5/6 hat einen CSS-Anzeigefehler, wenn man einem div gleichzeitig margin und float zuweist. Er verdoppelt in diesem Fall das margin auf der float-Seite, die gesamte Box wird um 1x margin verschoben.

Ja was denn nun, kein padding und kein margin, oder kein float, wie soll ich denn nun mit CSS ein vernünftiges Layout hinbekommen? Also doch zurück zur Tabelle, oder dem ganzen soviel Luft geben, dass es doch funktioniert und die unterschiedlichen Darstellungen der verschiedenen Browser in Kauf nehmen? 

Die Lösung: Aussenbox ohne alles

Die Lösung ist eigentlich ganz einfach:

Das ganze Boxmodell-Chaos resultiert doch nur daraus, wie und wo margin, border und padding in Relation zu width in den verschiedenen Browsern angezeigt werden.

Ist width definiert und sind marging, border und padding auf 0 gesetzt, sieht die Box in jedem Browser gleich aus.

Ist width NICHT definiert, nimmt die Box die gesamte zur Verfügung stehende horizontale Breite des Elternelementes ein, jetzt kann ich margin, border und padding Werte zuweisen, und trotzdem sieht auch in diesem Fall die Box in allen Browsern gleich aus.

Nun muss ich das ganze nur noch sinnvoll kombinieren.

Der äusseren div-Box wird width und float zugewiesen. Margin, border und padding werden auf 0 gesetzt. Jetzt kann der IE5/6 das margin dieser Box ruhig verdoppeln, 2×0=0 ;-) . Diese äussere Box wird das Elternelement der inneren Box.

Die innere Box bekommt KEINE width-Zuweisung !!!

Da sich die innere Box ohne width-Zuweisung in ihrer Gesamtbreite incl. margin innerhalb der äusseren Box maximal ausbreitet, kann ich die innere Box nun mit allen nur möglichen Angaben von margin, border und padding innerhalb der äusseren Box verschieben. Der gesamte horizontale Raum, den diese verschachtelte Box einnimmt, entspricht immer genau der width-Zuweisung für die äussere Box.

Ich habe jetzt genau DIE Box, die ich für das Layout brauche. Und das völlig ohne CSS-Hacks, mit einer Verschachtelungstiefe von lediglich 2.

Da frage ich mich doch ganz einfach, wozu jemals ein Boxmodell-Hack erfunden wurde. Oder ist das hier schon einer? ;-)  

Beispiele

Hier ein Codebeispiel für eine Box, die horizontal 400px einnimmt und 360 px incl. Rahmen breit ist:

<div style="float: left; width: 400px; border: 0; padding: 0; margin: 0; background-color: #dddddd;">
<div style="border: 10px solid #999999; padding: 20px; margin: 20px; background-color: #ffffff;">
<p>Der Inhalt</p>
</div>
</div>

Die für die Inhalte zur Verfügung stehende Breite beträgt 1×400px(width) – 2×20px(margin) – 2×10px(border) – 2×20px(padding) = 300px.

Und so sieht diese Box aus. Das margin der inneren Box habe ich sichtbar gemacht, indem ich der äusseren Box als Hintergrundfarbe hellgrau zugewiesen habe.

x
x
x

 

Und so könnte diese Box zum Einsatz kommen.

Das margin der inneren Box habe ich unsichtbar gemacht, indem ich aus der äusseren Box die Hintergrundfarbe entfernt habe.

Der Rahmen wurde auf 1px reduziert und margin-left auf 0 gesetzt. Beides kommt der Breite zugute, die dem Inhalt zur Verfügung steht.

Zuletzt wurde dann der inneren Box eine andere Hintergrundfarbe verpasst.

Diese Box nimmt genau den gleichen horizontalen Platz ein wie die obere. Das margin auf der rechten Seite sieht man nicht, doch die 3 "X" oben rechts von der Box machen es erkennbar.

x
x
x

Das funktioniert in allen mir bekannten Browsern. Sollte jemand einen Browser finden, in dem diese Box nicht korrekt dargestellt wird, bitte ich um kurze Mitteilung. Browser, die kein CSS verstehen, wie z. B. der NN4, lassen wir mal aussen vor, der Browser sollte nicht älter sein als IE5.

Hier bekommt Ihr die Boxen auf einer Art Millimeterpapier präsentiert und noch einmal erklärt und kommentiert:

Testseite »

Nachtrag: Ich bin von kompetenter Seite darauf aufmerksam gemacht worden, dass ich in meinem Beispiel nur auf pixelgenaues, festes Layout eingehe. Deshalb hier noch ein Beispiel, wie das ganze genauso gut mit relativen Werten und einem liquid design funktioniert:

Testseiten liquid design »

 

Suchbegriffe:

Boxmodell Box-Modell boxmodel box model, CSS-Boxmodell css-Boxmodell css-box-model.

HTML html, CSS CSS3, CSS 3, CSS2 CSS 2, css css3, css 3, css2 css 2. CSS-Layout, Layout, tabellenloses Layout, tabellenloses CSS-Layout, tabellenloses CSS Layout. Boxmodell Box-Modell boxmodel box model, CSS-Boxmodell css-Boxmodell css-box-model. Probleme mit CSS-Layout in verschiedenen Browsern und die Lösung. padding margin border float usw., browsersicheres Layout.

 

Mittwoch, 2. Mai 2007, 12:22 Uhr

zum Kommentar-Eingabeformular (Kommentare überspringen) »

4 Kommentare zu “CSS Boxmodell Chaos – die Lösung”

  1. Holger
    Am 14. Juni 2007 um 16:41 Uhr

    Der Artikel hat mir sehr geholfen. Vielen Dank!

    MfG Holger

  2. Ingo
    Am 20. Juli 2007 um 15:23 Uhr

    Super Artikel suche schon lange einen in dem das thema mal ordentlich behandelt wird !

    grüße
    i.schubert aus berlin

  3. Carina
    Am 5. August 2007 um 16:34 Uhr

    So ohne Daseinsberechtigung sind die diversen Box Model Hacks ja auch wieder nicht. Immerhin müllt man nicht zugunsten von Kinderkrankheiten eines einzigen Browsers das Markup mit unnützen divs ohne semantischen Wert zu. Sollte man sich irgendwann entschließen, den IE5 nicht mehr zu unterstützen, ist es leichter, ein paar Hacks an zentraler Stelle zu entfernen als hunderte überflüssige divs, die sich mit der Zeit angesammelt haben.

    Aber jemand der sich 2007 noch mutig zu Tabellenlayouts bekennt, sieht das vermutlich nicht ganz so kritisch (das hab ich mir jetzt nicht verkneifen können, sorry ;-) ). Eh auch ein valider & funktionierender Standpunkt, jedem seine Meinung.

    Meine Lieblingsvorgehensweise ist noch immer: wo es nicht möglich ist (oder ich zu faul bin…), es zu umgehen während der Entwicklung schnelle Hacks (underscore o. Ä. ) verwende und zum Schluss alles raus und z.B. über Conditional Comments oder eine serverseitige Browserweiche einbinden. Betrifft, wenn man den Quirks Mode vermeidet, ja ohnehin nur den IE 5 und irgendwann wird der hoffentlich endlich quasi ausgerottet sein. :-)

  4. GE
    Am 8. August 2007 um 19:58 Uhr

    Hallo Carina,

    auch ich bin faul, deshalb bevorzuge ich Lösungen, bei denen ich auch bei Erscheinen neuer Browser oder Browserversionen nix ändern muss. Das schont dann auch die Kasse meiner Kunden.

    Übrigens gab es auch in den 70er Jahren Jungs, die mutig weiter mit kurzen Haaren herumgelaufen sind und dafür teilweise von den modebewussten Langhaarigen verspottet wurden. In dieser Phase befindet sich zur Zeit das Webdesign. Heute kann jeder Mann die Haare tragen, wie er will, irgendwann wird auch das Webdesign dahin kommen ;-) .

    Mutig finde ich es eher, auf das CSS-Boxmodell zu vertrauen. Das wird erst so richtig interessant werden, wenn mit CSS Level 3 Borderbox und Contentbox einführt werden. Was werden die Browser dann als Voreinstellung nehmen, wird es dazu Vorgaben vom W3C geben? Denn eigentlich ist ja der IE5 der einzige Browser, der mit einem vernünftigen Boxmodell arbeitet. Und dieses Boxmodell kommt mit CSS 3 wieder, zumindest erstmal als Option. Wird es, nachdem nun alle modernen Browser das standardkonform falsche Boxmodell verwenden, ein neues Boxmodell-Chaos geben? Werden wir vielleicht alle Boxen in allen Projekten deklarieren müssen?

    Mein hier geschilderter Umgang mit dem CSS-Boxmodell funktioniert sowohl als Borderbox als auch als Contentbox. Deshalb setze ich neben der Trennung von Inhalt und Layout (in einem sinnvollen Umfang) auch auf die konsequente Trennung von float und width auf der einen und padding, border und margin auf der anderen Seite. Kleine Kompromisse in Bezug auf die Semantik nehme ich dabei in Kauf.

    Und auch eine (selbstverständlich CSS-gestylte) Layout-Tabelle kann der Weiterentwicklung von CSS und Boxmodell gelassen entgegensehen.

    Kurze Haare sind eben pflegeleichter, egal, was gerade modern ist ;-) .


Schreibe einen Kommentar




Spamschutz

Das Ergebnis muss als Zahl (Ziffern) eingetragen werden.