Float
era, float
era pas… mais pourquoi ne pas utiliser la valeur inline-block
de la propriété display
?
Vous connaissez certainement les valeurs block
ou inline
, mais moins celle de inline-block
et pourtant elle peut vous servir dans bien des cas.
Voyons dans quelles conditions nous pouvons l’utiliser (de manière non exhaustive) dans un premier temps, puis dans un second temps quelques difficultés dans son utilisation.
Utiliser display: inline-block
Il s’agit de la valeur par défaut des éléments input
.
C’est pour cela que l’utilisation de cet élément est aussi simple : il reste à côté de votre label, vous pouvez en changer sa largeur, sa hauteur, ses marges, etc..
Le formulaire
Quelle transition !
« Bon allez, c’est juste pour le formulaire, je vais utiliser un tableau de mise en page pour ne pas m’embêter ».
Je le lis et le vois encore souvent dans les codes sources. (et je l’eus fait…)
Si ce n’est pas du tableau ce sera un jeu de float
et de clear
.
Je vous propose cette forme de mise en page pour formulaire.
Dans cette mise en page les label
passent d’un display
à valeur inline
à un display: inline-block;
Un élément en inline-block
peut recevoir une valeur de vertical-align
qui, par défaut, ne semble pas être la même sur IE et sur les autres navigateurs.
Notre code CSS va donc nous permettre d’avoir un comportement homogène.
Le HTML :
<form name="my_form" action="#result" method="post">
<p> <label for="nom">Nom</label> <input type="text" id="nom"> </p>
<p> <label for="email">E-mail</label> <input type="e-mail" id="email"> </p>
<p> <label for="sujet">Sujet</label> <input type="text" id="sujet"> </p>
<p> <label for="message">Message</label> <textarea id="message"></textarea> </p>
</form>
Le CSS :
input, textarea {
/*déjà en inline-block*/
width: 150px;
padding: 4px;
vertical-align: top;
}
#sujet { width: 250px; }
textarea {
width: 300px;
height: 5em;
}
label {
display: inline-block;
width: 100px;
margin-right: 20px;
vertical-align: top;
text-align: right;
}
Une navigation horizontale (éléments de liste)
Le deuxième cas où l’on peut remplacer aisément le float
par du inline-block
c’est celui d’une liste dont on souhaite dimensionner les liens placés sur une seule ligne.
La valeur par défaut d’un <li>
pour la propriété display
est list-item
. Cette valeur est connue pour ses styles par défaut (margin-start plus ou moins élevée, puce de liste de type disc
, saut de ligne, etc.).
Cette valeur par défaut du display
va nous poser problème si on veut placer tous nos liens sur une seule ligne.
Qu’à cela ne tienne, il nous suffit d’appliquer la valeur inline à la propriété display :
Le code HTML :
<ul>
<li><a href="#">Item 1</a></li>
<li><a href="#">Item 2</a></li>
<li><a href="#">Item 3</a></li>
<li><a href="#">Item 4</a></li>
</ul>
Le code CSS :
li {
display: inline;
list-style: none; /* pour enlever les puces sur IE7 */
margin: 10px;
}
Ce tronçon est plutôt simple, mais il a le mérite de supprimer les styles par défaut de notre liste.
Les liens sont un peu collés si on en reste là, on va donc leur appliquer de nouveaux styles :
li a {
display: inline-block;
width: 100px;
padding: 5px 10px;
text-decoration: none;
color: #fff;
font-weight: bold;
background: #999;
}
Aperçu
Le lien ainsi stylé peut subir autant de transformation que vous le désirez, lui appliquer un background et lui donner les dimensions que vous souhaitez devient un jeu d’enfant.
Quelques soucis…
Oui il y en a, sinon ça ne serait pas marrant !
Le cas Internet Explorer
En effet lorsque l’on souhaite appliquer un inline-block
sur un élément, la valeur est prise en compte par IE uniquement si celle par défaut de l’élément est inline
.
Pour les cas précédents, nous avions un <label>
à placer en inline-block
, ceci n’a pas posé de problème car la valeur par défaut de son display
est inline
(idem pour l’élément <a>
).
Dans l’exemple suivant nos éléments sont par défaut en block
. Le remplacement de cette valeur par inline-block
ne sera pas compris par IE (version inférieure à 8).
Mais il y a une astuce.
Sur une feuille de style alternative (code à placer entre les balises <head>
) :
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="styles-ie7.css" />
<![endif]-->
il vous faudra préciser (dans votre CSS) :
element {
zoom: 1; /*offre le layout à un élément (*)*/
display: inline;
}
(*)correction Raphaël
Pour IE un élément inline
qui possède le layout aura le même comportement qu’un inline-block
.
Le problème white-space
Venons-en à l’exemple.
Pour une raison qui ne nous intéresse pas, je souhaite afficher trois divisions les unes à côté des autres, je sais que la place disponible en largeur est de 900px :
<div class="container">
<div><p>Lorem Elsass ipsum bredele [...]</p></div>
<div><p>Lorem Elsass ipsum bredele [...]</p></div>
<div><p>Lorem Elsass ipsum bredele [...]</p></div>
</div>
En utilisant ce code CSS je devrais pouvoir afficher mes éléments les uns à côté des autres :
.container {
width: 900px;
}
.container div {
display: inline-block;
width: 300px;
}
En effet chaque div
fait normalement 300px de largeur, comme nous en avons trois nous rentrons précisément dans les 900px du conteneur.
Sauf que l’indentation de notre code fait apparaître un espace blanc (white-space
) d’environ 4px entre chaque élément.
Une des solutions est de ne plus indenter la partie du code concernée. Cela vous obligerait à accepter de ne plus « aérer » certaines parties de votre code… pas super pour la lisibilité.
Une autre solution consiste en l’utilisation de commentaires HTML, de cette manière :
<div class="container exemple"><!--
--><div><p>Lorem Elsass ipsum bredele [...]</p></div><!--
--><div><p>Lorem Elsass ipsum bredele [...]</p></div><!--
--><div><p>Lorem Elsass ipsum bredele [...]</p></div><!--
--></div>
Pas super pratique, surtout si pour le code généré vous n’avez pas entièrement la main dessus (plugins ou fonctions WordPress, ou pas envie de tout modifier).
La dernière solution est de passer par du CSS.
Il nous faut « supprimer » le white-space
entre les div
. Pour cela nous appliquons la valeur nowrap
à cette propriété sur le conteneur. Cette valeur étant héritée, nous restaurons la valeur par défaut sur les enfants du conteneur.
.container {
width: 900px;
white-space: nowrap;
}
.container div {
display: inline-block;
width: 300px;
white-space: normal;
}
Edit : Après l’intervention de Raphaël j’ai effectué quelques tests qui montrent que la suppression des espaces n’est pas effective. Les éléments sont bien alignés mais dépassent de leur parent. Pourtant la méthode permet bel et bien un alignement des éléments et est comprise par tous les navigateurs que j’ai pu tester (Safari, Chrome, Firefox, IE>7, Opera, sous XP, Vista et Seven)…
Voici cependant une solution apportée par Raphaël (toujours le même) sur son espace de jeu : http://www.ie7nomore.com/fun/white-space/, ici l’aspect « root em » (rem) ne nous intéresse pas (bien que je vous invite à découvrir son utilité), c’est la simple annulation de la valeur font-size
sur le parent qui est intéressante. Elle a pour effet de supprimer les espaces indésirables, mais vous oblige à utiliser une valeur de corps en pixels pour les enfants.
Une fois ce travail d’alignement effectué, il arrivera probablement que le contenu ne soit pas aligné à la vertical comme vous le souhaitez.
Pour cela je vous rappelle que nous avons la propriété CSS : vertical-align
.
Souvent bien pratique de choisir la valeur top
pour placer les éléments en haut de leur conteneur, il vous arrivera probablement de devoir aligner les éléments entre eux de manière centrée (middle
) ou tout en bas du conteneur (bottom
).
Merci pour votre lecture 😉
N’hésitez pas si vous avez des exemples ou des contre-exemples d’utilisation…
Salut Padawan,
Voilà un bel article !
Deux petites remarques rapides :
– le commentaire « inutile si vous avez déjà précisé des dimensions (width ou height) » n’est pas vrai car en pratique les propriétés width et height ne confèrent pas le Layout si l’élément est en display inline (c’est assez peu connu)… cf. un livre que je te recommande 😉
– l’astuce du white-space: nowrap; ne fonctionne pas chez moi (testé sur FF 3.6, Opera 11 et Chrome 10) avec ton exemple. Tu l’as testé ?
Dans certains cas bien particuliers, il m’est arrivé d’utiliser cette propriété pour me dépatouiller quand l’intégration devenait un peu trop compliquée, typiquement sur http://www.pnlcoach.com/pnl-coaching-formation-pnl.php , dans la navigation #filarianeformations , comme ce sont des liens mis côte à côte, ça s’y prêtait bien.
Et effectivement, j’ai dû supprimer tout contenu entre lesdits liens… un display:none sur le » | » qui les sépare a fait l’affaire. Histoire de garder un caractère entre les lien.
Merci pour ce complément Raphaël, je modifie l’article 🙂
Tu parles de ce magnifique livre ? :p
J’ai effectué les tests sur cette page : http://www.creativejuiz.fr/blog/doc/display-inline-block.html#white-space-css, l’astuce fonctionne sur Firefox 3.6 (XP et Seven), Chrome 10 (XP), Chrome 9 (Seven), IE8 (XP), Opear 11 (XP), Safari 5.0 (XP).
Marrant que ça ne fonctionne pas chez toi…
Merci pour cet exemple Nico ; ça rappelle qu’il faut bien prendre cette valeur comme un outil supplémentaire et ne pas le mettre à toute les sauces, comme tout quoi :p
En fait, sur ta page de test, les whitespace ne sont pas supprimés (essaye de mettre un background sur .container div) mais uniquement devenus incompressibles donc les 3 blocs restent en ligne en débordant de leur parent 😉
Bien joué !
Effectivement ils ne sont pas supprimés…
Voyant que ça fonctionnait je n’ai pas testé en attribuant des backgrounds de différentes couleurs aux éléments.
Merci pour ce correctif… du coup faut que je revois ce morceau de l’article…
Du coup je trouve ça marrant que tous les navigateurs l’interprètent de la même manière.
Je crois que je vais davantage me concentrer sur la lecture de ton nouveau livre 🙂
Je trouve l’approche inline-block très intéressante pour faire du contenus en plusieurs colones, mais je l’ai essayé sur explorer 7 (autant l’aperçu que simplement le code que vous donniez) et ça ne fonctionne malheureusement pas.
Dans mon cas, ce n’est pas un problème d’espacement, mais bien de positionnement. Ce que je veux dire c’est que les trois inclus dans le .container sont affiché les uns en dessous des autres tous collé comme s’ils étaient un gros paragraphe.
Bonjour,
Merci pour ce retour.
Effectivement le code que je fournis (l’exemple) est allégé de tout fallback pour IE.
Logiquement il serait nécessaire d’inclure une feuille de styles alternative pour IE7 à la suite des styles globaux et d’y ajouter le code suivant :
.container p {
zoom: 1;
display: inline;
}
Mais la bidouille proposée avec white-space reste de la bidouille, dans le cadre d’un design très précis la meilleure solution consiste en la suppression dans le code des espaces blancs (soit par commentaire html, soit en supprimant réellement l’indentation du code).
Autrement il ne faut pas oublier la propriété
float
qui reste très utile dans bien des cas 🙂Bonne continuation Josée.
Hello,
j’ai utilisé ces fonctions pour centrer verticalement 3 blocs.. Super utile !
Sinon, c’est automatiquement des tableaux… ou alors je n’ai pas compris comment vertical-align fonctionnait… 😉
En tout cas, merci pour la découverte 😉
J
Merci pour ton retour 🙂
Vertical-align est souvent mal compris parce que méconnu ou trop souvent utilisé dans les tableaux, pour lesquels il est vrai que l’utilisation est vraiment facile à comprendre (génération tableur ?).
Un petit article de Dew sur Alsacréations :
http://www.alsacreations.com/astuce/lire/4-alignement-vertical-image-texte.html
Il y en a d’autres intéressants sur Alsa’.
Le mieux pour comprendre un peu plus vertical-align est de se faire une page vierge de contenu et de faire des tests avec des images, des éléments en ligne, en bloc, etc..
Bonne continuation Jess 😉
Merci, j’avais effectivement lu pas mal d’articles à ce propos sur alsa, pour aider un ami à centrer verticalement texte plus image… 🙂
En tout cas, grâce à display: inline-block, j’évite de faire flotter mes div, maintenant ^^
merci pour le lien.
bonne continuation à toi 🙂
Bonjour,
Merci pour cet article, qui est très intéressant !
J’ai testé la partie « trois divisions les unes à côté des autres », qui fonctionne effectivement sur Firefox 7.0.1, mais pas sur IE 7.
Quelle solution préconises-tu pour IE 7, les float ?
Merci !
Bonjour,
Merci pour ton commentaire.
Mon article fait mention d’une solution qui permet de simuler le comportement
inline-block
pour IE < 8.Rencontres-tu un souci pour implémenter cette solution ?
Sinon des fois les
float
c’est pas trop mal quand même 😀Au plaisir 😉
J’ai relu un peu tous ces articles ayant eu quelques soucis de positionnement pas plus tard qu’hier ! Je trouve très bizarre qu’il n’y ait pas de méthode « saine » pour supprimer le white-space du inline-block, je trouve encore plus bizarre le fait que l’indentation influe directement sur le code (on n’est pas dans une balise pre bordel !).
Sinon ce que l’article sur l’alignement vertical ne mentionne pas, c’est dans quelle mesure on peut utiliser l’alignement vertical et avec quelles balises. Jusqu’à maintenant je pensais qu’on ne pouvait l’utiliser que sur des table-cell ou des inline-block…
Hello,
La balise
pre
va faire bien pire, mais je comprends ton agacement 🙂Sinon pour l’alignement vertical, c’est bien ça, il ne s’applique que sur les éléments « inline-level » et « table-cell ». Un élément au display de type inline-block, devient en quelque sorte un élément « inline-level ».
Au plaisir 😉
Hello !
Post très intéressant, je suis personnellement un grand fan de ce positionnement, depuis que j’ai lu le bouquin de raphaël qui en vantait les mérites. D’ailleurs, je m’étonne qu’il ne soit pas plus vanté dans Knacss – que je découvre en ce moment, beau boulot – pour des designs faits par un graphiste sous Photoshop je le trouve plus maniable que display:table et parfois même les flottants.
Perso j’utilise la méthode des commentaires pour m’affranchir du whitespace, bien penser à vérifier l’alignement vertical ( le rendu varie aussi entre Gecko et WebKit), mais attention, selon mes souvenirs le validateur W3C n’apprécie pas les commentaires « vides »!
Bonne continuation à tous et continuez de rendre le web universel 😉
Même après deux ans, l’article est toujours aussi intéressant, merci !
Je viens de découvrir ton site, vraiment sympa je dois dire, et hop dans les marque-pages 🙂
Même 2019 ton site est toujours pratique pour ce qui débute merci direct mes favoris
moi j’utilise autre chose, c’est un peu + simple(?) que toute la panoplie display:inline-block, vertical-align:top, white-space:no-wrap (qui marche pas partout) (ou commentaires sur CHAQUE li), à chaque fois et pour tous les navigateurs.
voici:
.table-cell { pour tous sauf iE7
display:table-cell;
}
(<= aucun pb avec whitespace, vertical-align)
.ie7 .table-cell { pour IE7
display:inline; zoom:1;
vertical-align:top;
}
ensuite si on fait un script jquery, pour ajouter, si le navig est IE7, une classe table-cell-ie7 (=.ie7 .table-cell) à chaque balise ayant une classe table-cell (ou la prop display:table-cell), ca se résume juste à:
.table-cell {
display:table-cell;
}
c’est tout. en plus, pour passer au fluid design, c’est aussi + simple (on a pas à annuler toute la panoplie de prop css qu’on a positionné avec le inline-block)
pour les utilisateurs de IE7, ce sera lègèrement + lent à cause du script, mais tant pis pour leur gueule (z’onka actualiser leur navigateur à IE8 qui est déjà bien archaique => beau message ‘navigateur obsolète changez de version pour I8 minimum siouplait, sinon on ne garantit rien’-)
Bonjour Laurent,
Ta solution est utilisée par Apple sur son menu, elle a le mérite de répartir automatiquement la largeur disponible entre les « cellules ».
Cependant il ne faut pas comparer les deux solutions qui ne répondent clairement pas aux mêmes problèmes, et ne proposent pas le même support navigateurs. De même dans certaines situations l’utilisation de table-cell va te bloquer. Il faut donc analyse d’abord les besoins, puis comparer les solutions en fonction de leurs capacités à y répondre 🙂
Enfin, ne pas oublier que le but de l’article était de mettre « inline-block » à l’épreuve.
Concernant le JS pour IE7 (pas besoin de jQuery), il vaut mieux solutionner le problème en passant le budget sur l’accessibilité et en abandonnant ce vieux navigateur ! :p
Merci et bonne continuation.
« dans certaines situations l’utilisation de table-cell va te bloquer » peut-tu m’en dire un peu plus ?
Si tu souhaites utiliser des positionnements avancés comme de l’absolu tu vas être bloqué.
De manière générale, et peut-être avec des exceptions, les limites des tableaux classiques vont s’imposer également à ces « tableaux CSS ».
Je ne sais si c’est bon comme solution, mais j’ai essayé avec un margin-left négatif de 5px, et ça marche.
Amicalement
G. Rambault
Bonjour,
L’espacement dépend du lissage de la police, de la police utilisée, de la taille utilisée dans la contexte courant, ainsi que du navigateur, de la carte graphique et de l’OS.
Du coup la valeur de 5px est forcément fausse pour l’un de vos visiteurs.
Les seules bonnes solutions sont celles mentionnées dans cet article. Toute proposition à base de pixels est nécessairement faussée.
Bon courage.
Merci pour ces infos.
Hello,
Je trouve ton article sur inline-block très intéressant. C’est vrai que je ne l’utilise pas souvent pour ne pas dire jamais.
L’idée du inline-block pour les elements à la place du float est intéressante.
Maintenant, je me rend compte que du coup, le ne prend pas toute la place que prend son enfant . Une idée solution?
Hello,
Comme tu n’as pas échappé le code HTML mais j’imagine qu’un
display: block;
sur ton lien devrait fonctionner 😉Bonne soirée.