display: inline-block et IE7

Récemment, j'ai appris à la dure que IE7 n'interprétait pas correctement la valeur inline-block de la propriété display.

La haine presque généralisée pour IE existe depuis longtemps et je n'ai pas l'intention d'en ajouter. Mon but est de documenter ce petit problème que j'ai rencontré récemment.

Notez que je ne considère pas IE6 dans cet article, sauf exception, je ne supporte plus ce navigateur.

Qu'est-ce que inline-block?

Lorsqu'on applique la règle display: inline; à un élément, les propriétés affectant sa hauteur ne s'appliqueront pas.

Ce qui veut dire qu'une règle comme margin-top: 40px; ne s'applique pas à cet élément.

Par contre, si on applique la règle display: inline-block; à ce même élément, la valeur de margin-top s'applique. Le problème que j'ai rencontré est que ce comportement est correctement rendu par tous les navigateurs sauf IE7 (probablement IE6 mais je n'ai pas vérifié).

Exemple avec inline-block

Pour démontrer le problème, voici un block de code HTML, le CSS correspondant et le résultat dans Firefox 5 et IE7.

<h2>Exemple 1</h2>
<ul class="nav1">
<li class="nav1">item 1</li>
<li class="nav1">item 2</li>
<li class="nav1">item 3</li>
</ul>
li.nav1 {
display: inline-block;
margin-top: 40px;
border: solid 1px;
}
 

La première partie de l'image suivante montre le rendu dans FF5 et la seconde dans IE7.

Exemple de rendu de la valeur inline-block dans FF5 et IE7

On peut voir que IE7 traite la valeur inline-block comme block

Comment éviter le problème avec IE7?

Il existe 3 solutions pour contourner ce problème.

  1. Ne pas utiliser la propriété inline-block.
  2. Utiliser des hacks CSS
  3. Utiliser un commentaire conditionnel pour une feuille de style propre à IE (ce qui revient un peu à la solution 1).

Sans inline-block

Si on remplace simplement la valeur inline-block par la valeur inline, voici ce que nous obtenons dans tous les navigaeurs.

La valeur inline-block est remplacée par la valeur inline.

Le CSS présenté ci-haut devient ceci :

li.nav1 {
display: inline;
margin-top: 40px;
border: solid 1px;

}
On peut rapidement constater que la propriété margin-top n'est pas appliqué à un objet dont la propriété display est à inline. Pour obtenir un résultat semblable au niveau visuel, il faut transférer la propriété margin-top à l'élément parent qui est de type bloc; dans ce cas il s,agit de l'élément <ul>
ul.nav1 {
margin-top: 40px;
}

Le résultat visuel est le suivant :

inline et margin-top appliqué à l'élément parent

Mise à part le padding entre les éléments de la liste, le rendu est identique.

Par contre, il faut noter que cette solution ne s'applique pas à toutes les situations. Il y aura un problème si l'élément parent de niveau bloc affiche plusieurs lignes. La valeur de margin-top s'appliquera à la première ligne mais pas aux autres, possiblement pas à celle qui contient l'élément que vous vouliez affichez comme inline-block.

La solution illégale

La solution qui suit rendra votre feuille de style non conforme à la norme CSS 2.1. Si cela est important pour vous, c'est à éviter.

Voici le code CSS :

li.nav1 {
display: inline-block;
*display: inline;
*zoom: 1;
margin-top: 40px;
border: solid 1px;

}

Et voic le rendu dans FF5 et IE7 respectivement :

Les hacks CSS pour IE avec la valeur inline-block

Encore une fois, mis à part le padding, le rendu est très semblable.

Un commentaire conditionnel pour IE

La dernière solution consiste à créer une feuille de style propre à IE et à la lier de manière conditionnelle. Il s'agit d'insérer le code suivant dans l'entête de vos pages web:

 

<!--[if lt IE 8]>
<link rel="stylesheet" href="ie7_et_moins.css" />

<![endif]-->

Conclusions

Pour s'assurer que votre site s'affiche proprement dans tous les navigateurs, il faut tester, tester, tester. Le problème c'est qu'avoir tous les navigateurs à portée de la main n'est pas chose facile pour tout le monde. La plupart des navigateurs autres que IE sont disponibles sur les trois plate-formes principales (Windows, Mac et Linux). Par contre, pour les différentes versions d'IE, c'est problématique à moins d'avoir beaucoup de ressource. Un site très utile pour avoir un aperçu rapide  est IE NetRenderer, il permet d'avoir une capture d'écran de votre site pour les différentes versions d'IE. De plus, le service est gratuit.

Je ne suis pas sûr d'avoir trouvé la solution idéale puisque dans certains cas, il ne serait pas possible d'obtenir un rendu équivalent avec aussi peu de code que ce que j'ai utilisé. À tout le moins, j'espère que ces suggestions vous serviront de piste de départ pour trouver la meilleure solution si jamais vous rencontrez ce problème.