Grauzonen bei Cascading Stylesheets

Relative Werte und Vererbung

Im Falle von relativen Schriftgrößen leuchtet es ja noch unmittelbar ein, dass ein Kind-Element nicht den relativen Prozentwert für die Größe erbt, sondern den errechneten. Denn sonst hätte man bei einer Anweisung von font-size:84% spätestens beim Urenkel einer unlesbar kleine Schrift.
In den drei Beispielen wird jeweils folgende Element-Hierarchie dargestellt:

<div class="out"> Text innerhalb des div ...
  <div> Eingerückter Text, ...
    <p> Text auf der dritten Hierarchie-Ebene. <p>
  </div>
</div>
div.out { color:red; font-family:Helvetica; font-size:84%; }
div.blockquote { margin-left:40px; font-weight:bold; }
p { font-weight:normal; }
Text innerhalb des div Elements, der gegenüber dem normalen Text um 84% kleiner ist.
Eingerückter Text, der hier auch nur zur Verdeutlichung steht.

Text auf der dritten Hierarchie-Ebene. Wenn der über mehrere Zeilen geht, ist die Schriftgröße wohl eindeutiger zu erkennen.

div.out { color:red; font-family:Helvetica; font-size:84%; }
div.blockquote { margin-left:40px; font-weight:bold; font-size:84%;}
p { font-weight:normal; font-size:84%; }
Text innerhalb des div Elements, der gegenüber dem normalen Text um 84% kleiner ist.
Eingerückter Text, der hier auch nur zur Verdeutlichung steht.

Text auf der dritten Hierarchie-Ebene. Wenn der über mehrere Zeilen geht, ist die Schriftgröße wohl eindeutiger zu erkennen.

div.out { color:red; font-family:Helvetica; font-size:84%; }
div.blockquote { margin-left:40px; font-weight:bold; font-size:100%;}
p { font-weight:normal; font-size:100%; }
Text innerhalb des div Elements, der gegenüber dem normalen Text um 84% kleiner ist.
Eingerückter Text, der hier auch nur zur Verdeutlichung steht.

Text auf der dritten Hierarchie-Ebene. Wenn der über mehrere Zeilen geht, ist die Schriftgröße wohl eindeutiger zu erkennen.

Bei einem Standard konformen Browser (CSS1) müssen beim 1. und beim 3. Beispiel die Schriftgrößen jeweils gleich sein. Beim 2.Beispiel muss die Schrift mit jeder Hierarchiestufe kleiner werden. Wird der Standard nicht eingehalten, mag das anders sein. Jedenfalls sollte aber nie eine innere Stufe eine größere Schrift haben als eine äußere.

Die Regel ist: Kindelemente erben bei relativen Angaben den errechneten Wert vom Elternelement, nicht den relativen Prozentsatz.
Das ist eine geradlinige Aussage, soweit so gut. Daran schließt sich aber die nächste offene Frage an: "Was alles sind relative Werte?" Prozentangaben wird man ohne Zögern dazu zählen. Ebenso eindeutig komparative Ausdrücke wie smaller oder larger. Aber Längenmasse wie 1 em oder 2 ex, die sich eben an den Schriftmaßen orientieren, gehören auch dazu.
In dem Fall:

body { font-size: 12pt; text-indent:3em; }
p.big { font-size: 15pt; }

wird nämlich die Einrückung im Abschnitt mit der größeren Schrift auch 3 mal 12pt wie im ganzen anderen Text sein und nicht 3 mal 15pt.

Quelle: Cascading Style Sheets; Hakon Wium Lie, Bert Bos; Addison-Wesley

Überlappende Margins

Überschrift

Und das ist Text im normalen Absatz. Der Abstand nach oben zur Überschrift sollte etwas größer sein als der Abstand nach unten zum nächsten Absatz.

Die beiden Absätze überlappen sich vollständig, so dass der Abstand dazwischen nicht margin.bottom von einem plus margin.top vom anderen ist, sondern eben nur einmal margin.top (oder eben .bottom). Margin.bottom von der Überschrift ist üblicherweise größer als margin.top vom Absatz, deshalb kann der Abstand in dieser Konstellation nur auf minimal den Margin von der Überschrift zusammenschrullen.

Überschrift

Auch das ist wieder Text im normalen Absatz. Der Abstand nach oben zur Überschrift ist etwas größer als im vorangegangenen Beispiel, weil außer dem Abstand durch Margin auch noch zusätzlicher Abstand durch ein Padding dazu kommt.

Wenn keine Ränder um die Absätze gelegt sind und auch keine spezielle Hintergrundfarbe eingestellt ist, lässt sich nicht auf Anhieb sagen, ob der Abstand zwischen dem Text durch Padding oder durch Margin zustande gekommen ist.
Margins können sich überlappen, Paddings aber nicht. Das kann aber nicht das einzige Kriterium sein, bei der Entscheidung, ob ich jetzt zusätzlichen Abstand durch Padding oder durch Margin erzeuge. Padding-Flächen bekommen nämlich ihre Hintergrundfarbe vom jeweiligen Element selber (hier also <p> oder <h3>) während Margins die Hintergrundfarbe vom übergeordneten Element bekommen.
Man könnte jetzt denken, dass das für alle Eigenschaften so ist. Stimmt aber nicht. Wenn relative Abstände mit ex oder em festgelegt werden, ist die Bezugsgröße sowohl für Padding (das war zu erwarten), aber auch für Margin die Schrift des Block-Elements und eben nicht die des Parent.

Show Background    Show Borders
Das Margin Collapsing findet nur dann statt, wenn die vertikalen Ränder von Blockelementboxen, die sich im normalen Dokumentfluss befinden, aufeinander treffen. Die Ränder von Inline-Elementboxen, schwimmenden oder absolut positionierten Boxen verschmelzen nie miteinander. (Andy Budd, CSS Mastery, Addison-Wesley 2007)

Relative Positionierung

Alle Absätze in diesem Rahmen haben einen Margin von 10 Pixel und sind non-floating positioniert. Der mittlere Absatz demonstriert die Wirkungsweise von { position: relative }.

Dieser Absatz ist um 20 Pixel aus seiner normalen Position nach rechts verschoben und um 20 nach unten.

Die restlichen Absätze bzw. Boxen verhalten sich aber so, als würde der relativ verschobene Absatz sich noch an seiner ursprünglichen Stelle befinden. Das heißt es kommt zu Lücken und unter Umständen auch zu Überlappungen.

20 px    10 px    0 px

Floating Material


.------------------------------------------
| axaxax axaxax axaxax axaxax axaxax axax
| +-----------+ ax ax [flObj] axaxax axax
| |           | axaxax axaxax axaxax axax
| |  flObj    | axaxax axaxax axaxax axax
| |           | axaxax axaxax axaxax axax
| |  float:   | axaxax axaxax axaxax axax
| |    left   | axaxax axaxax axaxax axax
| |           | axaxax axaxax axaxax axax
| +-----------+ axaxax axax axax axax axa
| uegadf whoduwr had hqer lue hera hwersw
| axaxax axax aqguewrsdf -- aersfqwr asrd
| pwrsfa qacvbqa. qadsweldat sarf ahrs ww
| ax ax [frObj] axaxax axax +-----------+
| axaxax axaxax axaxax axax |           |
| axaxax axaxax axaxax axax |  frObj    |
| axaxax axaxax axaxax axax |           |
| axaxax axaxax axaxax axax |  float:   |
| axaxax axaxax axaxax axax |    right  |
| axaxax axaxax ax          |           |
|                           |           |
|                           +-----------+
|.--------------------------------------.
|| Header h3  clear:right               |
|'--------------------------------------'
|Clear:right means this block element does
|not tolerate any floating material on its
|right side.
'------------------------------------------

Wer noch aus der alten HTML 3.2 Welt kommt, hat es mitunter schwer, das Modell der floating Boxes von CSS zu verstehen. Das liegt vor allen Dingen daran, dass man noch aus alten Netscape Zeiten von dem <br clear=all> geprägt ist. Dieses Tag wurde gerne als "Zeilenumbruch extra stark" verstanden, weil es nicht nur eine neue Zeile begann, sondern auch alles bis dahin aktiviertes Umfliessen von Text um Bilder deaktivierte. "Wo clear steht ist floating zu Ende!", sagte sich der HTML Designer.

Bei CSS gilt aber prinzipiell: Egal ob "float" oder "clear", beide Attribute beziehen sich nur auf das Block-Element (manchmal auch inline Element) zu dem sie gehören. Konsequenterweise gibt es ein clear Stil Attribut für ein "Null-Element" wie <br> nicht mehr.
Während "float" aussagt, dieses Element darf bei der Darstellung seinen aktuellen Platz in der Reihenfolge des HTML Codes verlassen und an den linken bzw. rechten Rand der übergeordneten Box wandern, besagt "clear" rechts oder links wird kein floatendes Element geduldet. Das bedeutet aber nicht, dass dann das floatende Element verschoben wird, sondern dass das mit "clear" versehene Element soweit nach hinten/unten rutscht, bis es einen Platz gefunden hat, wo es direkt am Rand des Eltern-Elements zu liegen kommt. Denn nichts anderes als direkt am Rand bedeutet die Regel "rechts oder links darf kein floating Element stehen -- zumindest, wenn das Element mit dem clear ein Block-Element ist, den das nimmt automatisch den Platz vom linken Rand des Parent-Elements bis zum rechten Rands des Parents ein. Genau deshalb ist eine Kombination von float und clear beim gleichen Element auch sinnvoll: Damit wird nämlich festgelegt, dass dieses Element sehr wohl von seinen Platz wegbewegt werden soll, aber nur direkt an den Rand (es duldet ja kein anderes Floating-Objekt zwischen sich und dem Rand). Wenn kein anderes Floating-Objekt vorhanden ist, verhält sich float mit clear wie ein einfaches float. Wenn aber ein Float-Objekt in diesem Bereich schon am Rand angeordnet ist, dann kommt "clear" zur Wirkung. Und zwar in der Form, dass das Objekt nicht neben das schon vorhandene Floating Objekt gesetzt wird (wenn von der Breite der Umgebung genug Platz dafür da wäre), sondern sich seinen Platz direkt am Rand des Eltern-Objekts, also unter dem schon vorhandenen Float-Objekt sucht.

Box Formatting

Paragraphen werden gemäß HTML-4 und CSS als Boxen angesehen, und zwar üblicherweise als "block" Elemente und nicht als "inline" Elemente. Trotzdem ist es erlaubt, einen Absatz per Style-Definition als inline zu markieren. Bei den meisten Browsern wird sich dadurch nicht viel in der Darstellung ändern. Zumindest Mozilla-basierte Browser orientieren sich aber bei der Umstellung auf inline nicht mehr am Parent-Element für die Berechnung der Breite sondern am Text-Content, wie bei allen anderen gängigen inline Elementen auch. Der Internet Explorer behandelt einen Inline-Absatz immer noch als Box, die über ihre Außenmaße definiert wird, ordnet sie aber nicht mehr zwingend am linken Rand des Containers an. Er macht also das daraus, was andere Browser dann machen, wenn sie floating Boxen anordnen müssen. Interessant ist auch das Verhalten, wenn so ein Paragraph als "floating" deklariert wird. Dann wird nämlich implizit die Display-Eigenschaft von "inline" auf "block" umgestellt, was zu einer Änderung der Breite führt.
Die graue Box enthält übrigens nur ein non-breakable space. Das scheint für manche Browser ein Anlass zu sein Unter- und Oberlänge anders anzusetzen, weshalb sie zu einem veränderten Margin kommen.

In der folgenden Demo lässt sich das nachvollziehen, wenn Floating-Style und Margins mit den Formular-Elementen ändert. Die aktuellen Style-Attribute werden per Javascript ausgelesen und in das "title" Attribut der Absatz-Boxen geschrieben, so dass man sie als Tooltip sehen kann, wenn man die Maus eine Zeit lang über die Boxen hält. Im non-floating Mode haben der blaue und der grüne Absatz das inline Attribut.

First Paragraph

 

Number Three.

Four.

I am box 5, with an inline attribute and a width and height, that is predefined by settings in the style sheet. As "inline" I might be spread over multiple lines.

Paragraph 6 with a few words of text.

Box-7, another inline.

Normal Paragraphs    Floating Boxes (left)    Float right

Margin:    Horizontal Margin:

min-width bzw. max-width Workaround

Der Internet Explorer unterstützt zumindest bis einschließlich Version 7 keine min-width bzw. max-width Attribute in Style-Angaben für Block-Elemente. Als Workaround kann man entweder Javascript Expressions für Style-Werte benutzen -- die wiederum nur der Internet Explorer, aber kein anderer Browser unterstützt -- oder man bastelt einen onresize Handler, der dann eben nur aktiviert wird, wenn die Seite vom Internet Explorer gerendert wird.

function setMaxWidth() {
    var e = document.getElementById("maxwidth");
    e.runtimeStyle.width = document.body.clientWidth > 600 ? "600px" : "auto";
}

/* ... and active an on-resize handler with this function */

if ( -1 != navigator.userAgent.indexOf("MSIE") ) {
    window.onresize = setMaxWidth;
} 

In dieser Form greift die Methode nur beim Verändern der Fenstergröße vom Browser, nicht aber beim ersten Laden der Seite. Deshalb muss man auch noch einen direkten Aufruf der setMaxWidth() Funktion in den onload Handler des Body Elements der Seite einbauen.

Quelle: High Performance Websites; Steve Souders; O'Reilly