La Cascade

Un peu de tout sur CSS, HTML, SVG et JS,traduit du web anglophone
Rechercher

Approfondir la propriété display : les deux valeurs de display

par Rachel Andrew, 4 mars 2020, css, flexbox, cssgrid, article original paru le 8 avril 2019 dans Smashing Magazine

Nous parlons beaucoup de Flexbox et de Grid Layout, mais ces méthodes de mise en page sont, à la base, des valeurs de la propriété CSS display, une puissante propriété qui ne reçoit pas toute l'attention qu'elle mérite. Rachel Andrew y jette un coup d'œil dans une courte série.


Une mise en page flex ou grid commence par la déclaration display: flex ou display: grid. Ces méthodes de mise en page sont des valeurs de la propriété CSS display. Nous avons tendance à ne pas beaucoup parler de cette propriété en tant que telle, nous concentrant plutôt sur les valeurs de flex ou de grid. Cependant, il y a des choses intéressantes à comprendre au sujet de display et de la façon dont elle est définie, qui vous faciliteront grandement la vie lorsque vous utiliserez CSS pour votre mise en page.

Dans cet article, le premier d'une série de deux, je vais examiner la manière dont les valeurs de display sont définies dans la spécification de niveau 3. Il s'agit d'un changement par rapport à la façon dont nous définissions display dans les versions précédentes de CSS. Même s'ils peuvent déranger, de prime abord, ceux d'entre nous qui font du CSS depuis de nombreuses années, je pense que ces changements aident vraiment à expliquer ce qui se passe lorsque nous modifions la valeur display d'un élément.

Éléments block et inline

L'une des premières choses que nous enseignons aux personnes qui découvrent le CSS, ce sont les concepts d'éléments en block et inline. Nous expliquons que certains éléments de la page sont display : block et qu'ils possèdent, de ce fait, certaines caractéristiques. Ils s'étirent dans le sens de la ligne, en occupant tout l'espace disponible. Ils s'ouvrent sur une nouvelle ligne ; nous pouvons leur donner une largeur, une hauteur, une marge ainsi qu'un remplissage, et ces propriétés éloigneront d'autres éléments de la page.

Nous savons également que certains éléments sont display : inline. Les éléments en ligne sont comme les mots d'une phrase ; ils ne provoquent pas un saut à la ligne, ils réservent un caractère d'espace blanc entre eux. Si vous ajoutez des marges et du padding, ces éléments s'afficheront mais ne repousseront pas les autres éléments.

Le comportement des éléments block et inline est fondamental pour CSS et pour qu'un document HTML correctement balisé soit lisible par défaut. Cette disposition est appelée "Block and Inline Layout" (disposition en bloc et en ligne) ou “Normal Flow” (flux normal), car c'est la façon dont les éléments se disposent si nous ne faisons rien d'autre pour eux.

Valeurs internes et externes de display

Nous comprenons ces notions de block et inline, mais que se passe-t-il si nous appliquons display: grid à un élément ? Est-ce quelque chose de complètement différent ? Si nous regardons un composant sur lequel nous avons spécifié display: grid, en tant qu'élément parent dans la mise en page il se comporte comme un élément de niveau bloc. L'élément s'étire et occupe tout l'espace disponible dans la dimension en ligne, il commence sur une nouvelle ligne. Il se comporte exactement comme un élément de type bloc en termes de comportement par rapport au reste de la mise en page. Pourtant nous n'avons pas dit display: block, n'est-ce pas ?

En fait, il s'avère que si. Dans la spécification Display, niveau 3, la valeur de display est définie par deux mots-clés. Ces mots-clés définissent la valeur externe de display, qui sera inline ou block et définira donc comment l'élément se comporte dans la mise en page par rapport aux éléments qui l'entourent. Ils définissent également la valeur interne de l'élément — ou comment les enfants directs de cet élément se comportent.

Autrement dit, que lorsque vous écrivez display: grid, ce que vous dites réellement c'est display : block grid. Vous demandez un conteneur de grille de niveau bloc. Un élément qui aura tous les attributs de block - vous pouvez lui donner une height et une width, une margin et un padding, et il s'étirera pour remplir le conteneur. Les enfants de ce conteneur, cependant, ont reçu la valeur interne de grid et deviennent donc des items de grille. Le comportement de ces grid items est défini dans la spécification de grille CSS : la spécification de display nous donne un moyen d'indiquer au navigateur que c'est la méthode de mise en page que nous voulons utiliser.

Je pense que cette façon de considérer display est extrêmement utile ; elle explique de façon claire et directe ce que nous faisons avec les différentes méthodes de mise en page. Si vous deviez spécifier display: inline flex, à quoi vous attendriez-vous ? Eh bien sans doute à une boîte se comportant comme un élément inline, avec des enfants qui seraient des items flex.

Il y a quelques autres choses qui s'expliquent facilement lorsqu'on envisage display de cette nouvelle manière, et je vais en examiner quelques-unes dans la suite de cet article.

Nous revenons toujours au flux normal

Pour comprendre ces propriétés d'affichage internes et externes, il peut être utile d'observer ce qui se passe si nous ne modifions pas du tout la valeur d'affichage. Si nous écrivons du HTML et que nous l'affichons dans un navigateur, nous obtenons une disposition en bloc et en ligne, ou un flux normal. Les éléments s'affichent comme des éléments bloc ou en ligne.

voir Block and Inline Layout de rachelandrew dans CodePen

L'exemple ci-dessous contient des balises que j'ai transformées en objet média, en faisant en sorte que les div display: flex (les deux enfants directs) deviennent des items flex, de sorte que l'image se trouve maintenant dans une rangée avec le contenu. Si vous regardez le contenu cependant, il y a un titre et un paragraphe qui s'affichent à nouveau en flux normal. Les enfants directs de l'objet média sont devenus des items flex ; leurs enfants reviennent à un flux normal à moins que nous ne changions la valeur de display sur l'item flex. Le conteneur flex lui-même est une boîte de niveau bloc, comme vous pouvez le voir par le fait que la bordure s'étend jusqu'aux bords de son parent.

Si vous travaillez ainsi, les éléments de votre page se disposeront d'eux-mêmes avec cette belle disposition de flux normal lisible, plutôt que de lutter contre et d'essayer de tout placer. Vous êtes également moins susceptible de rencontrer des problèmes d'accessibilité, car vous travaillez avec l'ordre du document, ce qui est exactement ce que fait un lecteur d'écran ou une personne qui navigue dans le document via la tabulation.

Expliquer flow-root et inline-block

La valeur de inline-block est également susceptible d'être familière à ceux d'entre nous qui font du CSS depuis un certain temps. Cette valeur est un moyen d'obtenir certains comportements de bloc sur un élément inline. Par exemple, un élément inline-block peut avoir une largeur et une hauteur. Un élément avec display: inline-block se comporte également d'une manière intéressante en ce qu'il crée un contexte de formatage de type bloc (Block Formatting Context, BFC).

Un BFC fait certaines choses utiles en termes de mise en page, par exemple, il contient des floats. Pour en savoir plus sur les contextes de mise en forme des blocs, consultez mon article précédent intitulé "Understanding CSS Layout And The Block Formatting Context". Par conséquent, dire display: inline-block vous donne une boîte inline qui établit également un BFC.

Comme vous le découvrirez (si vous lisez l'article susmentionné sur le Contexte de formatage block), il existe une valeur plus récente de display qui crée aussi explicitement un BFC. Il s'agit de la valeur flow-root. Cette valeur crée un BFC sur un bloc, plutôt que sur un élément inline.

  • display : inline-block vous donne un BFC sur une boîte inline.
  • display : flow-root vous donne un BFC sur une boîte block.

Vous vous dites probablement que tout cela est un peu confus : pourquoi avons-nous deux mots-clés complètement différents ici, et qu'est-il arrivé à la syntaxe à deux valeurs dont nous parlions auparavant ? Eh bien cela nous amène justement à ce que je dois maintenant expliquer à propos de display : CSS a un historique dont nous devons tenir compte en termes de propriété display.

Valeurs historiques de la propriété display

La spécification CSS2 détaillait les valeurs suivantes pour la propriété display :

  • inline
  • bloc
  • inline-block
  • list-item
  • none
  • table
  • inline-table

Nous avons également défini les diverses propriétés internes du tableau, telles que table-cell, dont nous ne nous occuperons pas dans cet article.

Nous avons ensuite ajouté à celles-ci quelques valeurs pour l'affichage, afin de prendre en charge la mise en page flex et grid :

  • grid
  • inline-grid
  • flex
  • inline-flex

Remarque : la spécification définit également ruby et inline-ruby pour prendre en charge le texte Ruby, ce que vous pouvez lire dans la spécification Ruby.

Ce sont toutes des valeurs uniques pour la propriété display, définies avant que la spécification ne soit mise à jour. Un aspect fondamental de la construction de CSS est que nous ne devons jamais casser le Web ; nous ne pouvons pas simplement changer les choses. Nous ne pouvons pas décider soudainement que tout le monde doit utiliser cette nouvelle syntaxe à deux valeurs et que, par conséquent, tous les sites Web construits avec la syntaxe à une seule valeur se casseront si un développeur ne revient pas en arrière pour les corriger !

En réfléchissant à ce problème, vous apprécierez peut-être cette liste d'erreurs dans la conception de CSS qui sont moins des erreurs dans de nombreux cas que des choses qui ont été conçues sans boule de cristal pour voir dans l'avenir ! Cependant, le fait est que nous ne pouvons pas casser le Web, c'est pourquoi nous avons cette situation où actuellement les navigateurs supportent un ensemble de valeurs uniques pour l'affichage, et la spécification passe à deux valeurs pour l'affichage.

La façon dont nous contournons cette situation est de spécifier des valeurs anciennes et courtes pour l'affichage, ce qui inclut toutes ces valeurs uniques. Cela signifie qu'un mappage peut être défini entre les valeurs uniques et les nouvelles valeurs à deux mots-clés. Ce qui nous donne le tableau de valeurs suivant :

Valeur SimpleValeur en 2 motsDescription
blockblock flowBlock box with normal flow inner
flow-rootblock flow-rootBlock box defining a BFC
inlineinline flowInline box with normal flow inner
inline-blockinline flow-rootInline box defining a BFC
list-itemblock flow list-itemBlock box with normal flow inner and additional marker box
flexblock flexBlock box with inner flex layout
inline-flexinline flexInline box with inner flex layout
gridblock gridBlock box with inner grid layout
inline-gridinline gridInline box with inner grid layout
tableblock tableBlock box with inner table layout
inline-tableinline tableInline box with inner table layout

Pour expliquer comment ça marche, nous prenons l'exemple d'un conteneur de grille. Dans le monde à deux valeurs, nous créerions un conteneur de grille de niveau bloc avec :

.container {
  display: block grid;
}

Cependant, le mot-clé legacy fait la même chose :

.container {
  display: grid;
}

Si, à la place, nous voulions un conteneur de grille en ligne, dans le monde à deux valeurs, nous utiliserions :

.container {
  display: inline grid;
}

et avec les valeurs legacy :

.container {
  display: inline-grid;
}

Après ce petit détour historique, nous pouvons maintenant revenir au point de départ de cette conversation et nous pencher sur display: inline-block. En regardant le tableau, vous pouvez voir que c'est défini dans le monde à deux valeurs comme display: inline flow-root. Il correspond maintenant à display: flow-root qui, dans un monde à deux valeurs, serait display: block flow-root. Un peu de rangement et de clarification de la façon dont ces choses sont définies. Une refactorisation de CSS, si vous voulez.

Prise en charge de la syntaxe à deux valeurs par les navigateurs

Pour l'instant, les navigateurs ne prennent pas en charge la syntaxe à deux valeurs pour la propriété display. Le bogue d'implémentation pour Firefox peut être trouvé ici. L'implémentation — lorsqu'elle aura lieu — consistera essentiellement à aliaser les anciennes valeurs vers les versions à deux valeurs. Il faudra donc attendre un bon moment avant que vous puissiez réellement utiliser ces versions à deux valeurs dans votre code. Cependant, ce n'est pas vraiment le sujet de cet article. Je pense plutôt que le fait d'examiner les valeurs d'affichage à la lumière du modèle à deux valeurs permet d'expliquer une grande partie de ce qui se passe.

Lorsque vous définissez la disposition d'une boîte en CSS, vous définissez ce qui arrive à cette boîte en termes de comportement par rapport à toutes les autres boîtes de la mise en page. Vous définissez également le comportement des enfants de cette boîte. Vous pouvez penser de cette manière bien avant de pouvoir déclarer explicitement les valeurs comme deux choses distinctes, car les mots-clés hérités correspondent à ces valeurs, et ça vous aidera à comprendre ce qui se passe lorsque vous modifiez la valeur de display.

Voir la liste des articles de Rachel Andrew traduits dans La Cascade.

Autres ressources

Article original paru le 8 avril 2019 dans Smashing Magazine
Traduit avec l'aimable autorisation de Smashing Magazine et de Rachel Andrew.
Copyright Smashing Magazine © 2019