Hallo Gunther,
Grundlage für alle Beispiele ist, dass html und body jeweils eine Höhe und Breite von 100% haben (da ansonsten prozentuale Höhenangaben nicht relevant sind, was ich übrigens auch schon für falsch halte, denn 'logisch' wäre, wenn sie auf das Elternelement bezogen würden, was nach neuerer Denke das html-Element wäre, was ja letztendlich das Fenster repräsentiert und was sonst sollte 100% sein),
Da wäre schon mal der 'canvas' der in alle Richtungen unendlich ist (Enterprise läßt grüßen), dann kommt der viewport (z.B. ein Fenster), erst da kommen wir zum Root-Element (das wäre bei uns also html), das den sogenannten "initial containing block" für alle anderen Elemente erzeugt.
"The width of the initial containing block may be specified with the 'width' property for the root element. If this property has the value 'auto', the user agent supplies the initial width (e.g., the user agent uses the current width of the viewport)."
Also setzen wir html und body auf width:100% (wobei man eigentlich auch width:auto; nutzen sollte!) dann ist mal die "Seite" so breit wie das Fenster (theoretisch).
1. Beispiel:
<div id="d1" style="height:100%;width:100%;margin:20px;padding:0px;border:none;background-color:#ccc">
Inhalt von DIV 1
</div>
Der NS7 und OP6 zeigen beide nur den top- und left-margin an. OP7 immerhin zusätzlich auch noch den bottom-margin, und der MSIE6 zwar nicht den bottom-margin, dafür aber den right-margin (das sind meine 4 Test-Browser + NS4 - alle auf Win32-Plattform).
Und was haben wir jetzt (nach dem W3C Box Model)? Ein DIV-Element, welches eine Gesamt-Größe von 100%(Fenstergröße)+je 2*20px hat. Bei Padding und Border verhält es sich analog (nur mit ein paar anderen 'Browserabweichungen' in der Darstellung).
Da machen eben die Browser schon schlapp; und deine Interpretation läßt einiges außer Acht:
Es geht hier um ein normales <div> im normalen Kontext, also es geht um ein "Block-level, non-replaced elements in normal flow"
Für solche Elemente gilt:
"'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block "
Aber es gilt dabei folgendes (Sorry für die langen Zitate):
-----------------------------------------------------------
"If all of the above have a specified value other than 'auto', the values are said to be "over-constrained" and one of the computed values will have to be different from its specified value. If the 'direction' property has the value 'ltr', the specified value of 'margin-right' is ignored and the value is computed so as to make the equality true.
If there is exactly one value specified as 'auto', its computed value follows from the equality.
If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
If both 'margin-left' and 'margin-right' are 'auto', their computed values are equal. "
-----------------------------------------------------------
Nach dem für direction ltr als initial Wert gilt und in deinem Beispiel alle Eigenschaften einen Wert anders als "auto" haben, _muss_ "margin-right" ignoriert werden, d.h. Opera 7 macht es richtig.
Wenn ich jetzt aber bspw. innerhalb dieses DIV's ein weiteres DIV-Element setzen möchte, das zu allen Seiten einen festen Abstand von 50px hat, dann bist du mit dem Modell am Ende, denn das Padding (Innen-Abstand!) wird IMHO fälschlicherweise auf die Elementgröße draufgerechnet. Das ist das selbe, als wenn eine Tabellenzelle durch eine Padding-Angabe auf einmal größer würde!
Gehen wir darauf ein:
Nehmen wir 'width'
"width (welche ja nur die Breite vom Inhalt bestimmt) refer to width of containing block."
Weiter mit 'padding'
"The padding edge (das ist die immaginäre Linie an der äußeren Seite von der padding-Breite) of a box defines the edges of the containing block established by the box."
Der "containg block" wird so definiert:
"In general, generated boxes act as containing blocks for descendant
boxes; we say that a box "establishes" the containing block for its
descendants. The phrase "a box's containing block" means "the containing block in which the box lives," not the one it generates."
Also width + padding ergeben die Breite des "containing block", das ein Element für seine Kind-Elemente erzeugt (wohlgemerkt das margin und border nicht dabei sind!).
Und da müssen wir eben unterschieden zwischen den "containing block" in dem ein Element steht und den "containing block" den er für seine Kind-Element erzuegt.
Für die weitere Block-Level Elemente im body gilt:
"Block-level elements generate a "principal block box" that only contains "block boxes". The principal block box establishes the containing block for descendant boxes and generated content and is also the box involved in any positioning scheme. Principal block boxes participate in a block formatting context."
Und der "block formatting context" sagt:
"In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties.
In a block formatting context, each box's left outer edge touches the left edge of the containing block [...]"
Was eben bedeutet, dass die Gesamtbreite des Boxes nicht gleich die Inhaltbreite des Boxes ist, aber das wussten wir ja ohne hin.
Beispiel 2:
(Dieses Beispiel wird übrigens von allen Browsern 'korrekt' angezeigt!)
Postionierte elemente sind wieder ein ganz anderer Käse.
Und die Überlegungen des W3C bezüglich dieser Dinge bei CSS3 zeigen doch eindeutig, dass man sich scheinbar auch im Klaren darüber ist, dass das, was man da mit dem Box Model gemacht hat, nicht der Weisheit letzter Schluß war.
Ja, aber das ist doch nicht das Problem, oder? ;-)
Und das ist mein Hauptkritikpunkt: Dieses Modell macht es unmöglich ein 'größenvariables' Element mit absoluten Rand-, Rahmen- und/oder Innenabständen/größen zu definieren, welches nicht die Fenstergröße sprengt und diese dabei aber wie gesagt voll ausnutzen soll (was wie ich finde doch eine mehr als nützliche & sinnvolle Möglichkeit darstellt)!
Das macht es eben nicht!
Wenn man sowohl margin, padding und border mit anderen Werten als "auto" definiert, _müsste_ man "width" auf "auto" setzen, damit gemäß den Regel der Spez. die Rechung richtig ist.
Grüße
Thomas