Quand utiliser inline-block ?
La valeur inline-block pour l'affichage est un classique, mais à quoi sert-elle réellement et quand la choisirons-nous parmi d'autres options ?
La valeur inline-block
pour l'affichage est un classique ! Elle n'est pas nouvelle et la prise en charge par les navigateurs n'est certainement pas un sujet d'inquiétude. Je suis sûr que beaucoup d'entre nous l'utilisent intuitivement. Mais essayons de creuser un peu. À quoi sert-elle réellement ? Quand la choisirez-vous plutôt que d'autres options, peut-être similaires ?
Boutons
La réponse la plus fréquente que j'ai reçue c'est : Je l'utilise toujours pour aligner les boutons.
Au fond, ça fait sens, mais ça contribue à entretenir ce que je perçois comme une légère incompréhension. L'idée est qu'on veut aligner horizontalement des éléments qui ressemblent à des boutons (qui pourraient être des ancres, des boutons, des inputs) — comme ils le font naturellement — mais avec la possibilité d'avoir des marges et du padding. C'est là que réside la petite incompréhension : les éléments display: inline
peuvent toujours avoir des margin
et padding
, et se comportent probablement comme vous l'attendez.
Là où ça se complique, c'est que :
- la marge dans la direction block sur les éléments inline est entièrement ignorée
- le padding sur les éléments inline n'affecte pas la hauteur de la ligne de texte
Donc, même si les boutons eux-mêmes sont stylés comme il faut, l'élément parent et le texte qui l'entoure ne le sont sans doute pas. Voici une démo pour l'illustrer :
Les choses se compliquent encore quand la largeur de page se réduit :
Donc, oui, inline-block
fait sens pour aligner les boutons, mais...
N'oubliez pas inline-flex et inline-grid
Avec les valeurs d'affichage inline-flex
et inline-grid
, vous aurez le même (bon) comportement que vous attendez d'inline-block
, mais les éléments (souvent des boutons) bénéficient d'un système de mise en page plus solide.
Prenez l'exemple de boutons avec des icônes :
<a href="#" class="button>
<svg> ... </svg>
Text
</a>
Pour que le texte et l'icone s'aligent parfaitement au centre, il est tentant de faire :
.button svg {
vertical-align: middle;
}
qui ne réussit jamais exactement...
Mais on peut réparer ça facilement avec inline-flex
:
.button {
display: inline-flex;
align-items: center;
}
Avec inline-flex
ou inline-grid
on a toute la puissance de flexbox ou de grid à l'intérieur d'un bloc qui se met en page dans la direction inline.
Les blocks peuvent toujours revenir à la ligne
Un élément inline-block respecte une largeur. C'est une différence supplémentaire avec les éléments inline. On s'est habitué à construire des systèmes de mise en page par colonnes avec des éléments inline-block, parce qu'ils peuvent faire ce que que les éléments flottés pouvaient faire ici, mais sans avoir à s'inquiéter de faire un clear du float
(est-ce que les jeunes générations comprennent ce que je veux dire ?), ce qui permettait un retour à la ligne plus élégant que le float
.
L'idée d'avoir des inline-blocks se comportant comme des colonnes avec retour à la ligne (même avec une seule colonne) est toujours vivante aujourd'hui parce que c'est une astuce qu'on peut utiliser dans les emails html pour permettre des mises en page à plusieurs colonnes qui se résolvent en une seule colonne sur des écrans réduits sans avoir à utiliser les media queries (que certains clients email ne permettent pas.)
transform sur un élément inline
Les éléments inline ne peuvent pas prendre un transform
. Si vous en avez besoin, il faudra que ce soit un inline-block.
Des enfants de colonnes qui ne se cassent pas au milieu
Les colonnes CSS peuvent être utilisées avec des paragraphes de textes lorsque vous ne vous souciez pas qu'ils se cassent entre les colonnes. Mais parfois les colonnes CSS sont utilisées pour des blocs pour lesquels ce serait bizarre. Supposons que nos blocs aient leur propre background et padding. Ces ruptures sont vraiment bizarres visuellement
C'est une astuce étrange, dont je ne peux pas dire que je la comprends à 100%, mais si vous mettez display:inline-block
sur ces boîtes (et probablement width: 100%
pour être sûr) eh bien elles ne se casseront pas et la colonne sera préservée.
Une façon rapide de rendre une liste horizontale
Ça aussi, c'est assez populaire : les listes empilent les éléments verticalement, comme des éléments blocs. Mais ce ne sont pas des blocs. Ce sont des display: list-item
, ce qui est important comme nous l'allons voir. Le cas d'usage populaire est quand je veux aligner une liste horizontalement.
Donc, vous avez une liste...
<ul>
<li>Three</li>
<li>Little</li>
<li>Piggies</li>
</ul>
...vous voulez l'afficher horizontalement, vous pouvez...
li {
display: inline-block;
}
Et voilà.
J'ai écouté ce que disait VoiceOver (NdT: l'outil d'accessibilité) et la liste inline-block
est toujours annoncée comme une liste, mais elle n'annonce pas les puces (bullet points) ce qui fait sens puisqu'elles n'y sont pas. C'est le souci lorsqu'on change l'affichage des éléments de listes en n'utilisant pas display: list-item
, elles perdent en list-item-ité...
Une alternative pourrait être de faire du parent un container flex :
ul {
display: flex;
}
ce qui permet l'alignement horizontal (la valeur par défaut de flexbox) mais conserve les puces puisqu'on n'a pas modifié le display des élements de liste. Vous pouvez toujours les retirer manuellement si vous le souhaitez.
Listes centrées
À propos de liste, Jeff Starr a écrit un article sur l'idée de listes à l'intérieur d'un texte centré, qui peut sembler bizarre elle aussi. Ce qui est bizarre dans cette idée, c'est que le texte des éléments de la liste est centré, mais la liste elle-même est affichée en pleine largeur, ce qui crée cette situation où les puces sont alignées à gauche :
La solution de Jeff a été de mettre inline-block
la liste entière. Ça permet à la liste d'être aussi large que son contenu et permet aux puces de ne plus être accrochées au bord gauche et de voyager avec le contenu centré. Tant qu'il y a des éléments de niveau block avant et après, c'est une bonne solution.
Une alternative, si le but est de réduire la largeur de la liste à celle du contenant, pourrait être la suivante qui n'empêche pas la liste d'être de niveau bloc :
ul {
width: max-content;
margin: 0 auto;
text-align: left;
}