inline-block
– eine Alternative zu float
Dieser Artikel beschreibt Probleme mit float
bei Boxen mit verschiedener Höhe und zeigt eine Alternative: display: inline-block
.
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 |
---|---|
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.
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.