inline-block – eine Alternative zu float

Autor
Gunnar Bittersmann
veröffentlicht
2009-01-06
letzte kleinere Änderung
2009-05-14

Zusammenfassung

Dieser Artikel beschreibt Probleme mit float bei Boxen mit verschiedener Höhe und zeigt eine Alternative: display: inline-block.

Probleme mit float

Betrachten wir als Beispiel 6 floatende Boxen (li) in einer umschließenden Box (ol):

<ol> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ol>

Stylesheet:

ol { border: 1px solid #048; list-style: none; margin: 0; padding: 0 0 8px 0; overflow: auto; width: 158px; } li { background: #048; color: white; display: inline; /* IE doubled float-margin bug */ float: left; font: bold 32px Arial, sans-serif; margin: 8px 0 0 8px; padding: 0; text-align: center; width: 42px; }

So sieht es aus: Beispiel 1 | im Iframe:

Ändert sich die Breite der umschließenden Box (ol {width: 208px}), passt sich die Darstellung an: Beispiel 2 | im Iframe:

Bislang alles easy. Problematisch wird es, wenn die Boxen unterschiedliche Höhe haben. Geben wir der 2. Box mehr Inhalt:

<li>2 +</li>

Dann sieht es so aus: Beispiel 3 | im Iframe:

Da die 4. Box noch unter die 3. passt, beginnt sie nicht am Anfang einer neuen Zeile.

Nun kann man für jede n-te Box (in unserem Fall für jede dritte) eine neue Zeile erzwingen. Das ginge am einfachsten mit der Pseudoklasse :nth-child() [CSS3-SELECTORS]:

li:nth-child(3n+1) { clear: left; }

Aktuelle Opera, Safari und Chrome interpretieren diesen CSS3-Selektor bereits; Firefox erst ab Version 3.1; Internet Explorer bis Version 7 jedoch noch nicht: Beispiel 4 | im Iframe:

Um alte Browser zu unterstützen, ergänzen wir das Markup um eine Klasse für jedes n-te Element (dies kann auch durch serverseitiges Scripting geschehen, bspw. mit PHP):

<ol> <li class="firstInLine">1</li> <li>2 +</li> <li>3</li> <li class="firstInLine">4</li> <li>5</li> <li>6</li> </ol>

und geben für diese Klasse an:

li.firstInLine { clear: left; }

So sieht es aus: Beispiel 5 | im Iframe:

Internet Explorer wendet zwar das clear auf die jeweilige Box an, vergisst dies jedoch wieder bei der nachfolgenden Box, so dass die Darstellung fehlerhaft ist (Screenshots):

richtige Darstellung Darstellung im IE 6 und 7
richtige Darstellung Darstellung im IE 6 und 7

Und noch einen weiteren Nachteil hat die Lösung mit float: Man muss die Anzahl n der Boxen, die nebeneinander passen, festlegen (in unserem Beispiel 3). Das Layout ist nicht flexibel.

Spätestens jetzt ist es an der Zeit, eine brauchbare Alternative zu float zu suchen.

Die Alternative: display: inline-block

Die Lösung des Problems ist plausibel: Kein float verwenden! Stattdessen setzen wir:

li { background: #048; color: white; display: inline-block; font: bold 32px Arial, sans-serif; margin: 8px 0 0 8px; padding: 0; text-align: center; width: 42px; }

und da Internet Explorer dies nicht verstehen, für IE 6 und IE 7 mit Hacks

* html li { display: inline; } *:first-child+html li { display: inline; }

Da die li-Elemente nun keine CSS-Blockelemente mehr sind, wird im Quelltext vorhandener Whitespace zwischen ihnen dargestellt. Deshalb formatieren wir das Markup um – entweder das ganze ol-Element in einer Zeile

<ol><li>1</li><li>2 +</li><li>3</li><li>4</li><li>5</li><li>6</li></ol>

oder zur besseren Übersicht:

<ol><li>1</li ><li>2 +</li ><li>3</li ><li>4</li ><li>5</li ><li>6</li ></ol>

So sieht es aus: Beispiel 6 | im Iframe:

Das ist nicht ganz das Gewünschte, aber die vertical-align-Eigenschaft wirkt auf Inline-Blöcke und auch im IE tut sie ihren Dienst:

li { background: #048; color: white; display: inline-block; font: bold 32px Arial, sans-serif; margin: 8px 0 0 8px; padding: 0; text-align: center; vertical-align: top; width: 42px; }

So sieht es aus: Beispiel 7 | im Iframe:

Durch die Lösung mit display: inline-block ist das Layout flexibel; es werden soviele Boxen nebeneinander dargestellt wie nebeneinander passen: Beispiel 8 | im Iframe:

Einziges Sorgenkind ist der Firefox 2, der display: inline-block nicht unterstützt. Allerdings unterstützt er das proprietäre display: -moz-inline-grid:

li { background: #048; color: white; display: inline-block; display: -moz-inline-grid; font: bold 32px Arial, sans-serif; margin: 8px 0 0 8px; padding: 0; text-align: center; vertical-align: top; width: 42px; }

Leider muss man dazu noch den Inhalt jeweils in ein zusätzliches Block-Element tun (sofern noch kein solches vorhanden ist):

<ol><li><div>1</div></li ><li><div>2 +</div></li ><li><div>3</div></li ><li><div>4</div></li ><li><div>5</div></li ><li><div>6</div></li ></ol>

So sieht es aus: Beispiel 9 | im Iframe:

Inwiefern der Firefox 2 heutzutage noch relevant ist, muss jeder Webseitenautor für seine Zielgruppe selbst einschätzen. Die Tage des Firefox 2 sind bereits gezählt, Mozilla hat den Support eingestellt und ruft die Nutzer zum Upgrade auf Firefox 3 auf.

Referenz

CSS3-SELECTORS
Selectors, W3C working draft, 2005-12-15, http://www.w3.org/TR/2005/WD-css3-selectors-20051215; neuste Version verfügbar unter http://www.w3.org/TR/css3-selectors