Creuser dans la propriété d'affichage : les deux valeurs de l'affichage

Publié: 2022-03-10
Résumé rapide ↬ Nous parlons beaucoup de Flexbox et de CSS Grid Layout, mais ces méthodes de mise en page sont essentiellement des valeurs de la propriété display CSS, un cheval de bataille d'une propriété qui ne reçoit pas beaucoup d'attention. Rachel Andrew y jette un meilleur coup d'œil dans une courte série.

Une mise en page flexible ou en grille commence par la déclaration de display: flex ou display: grid . Ces méthodes de mise en page sont des valeurs de la propriété display CSS. Nous avons tendance à ne pas trop parler de cette propriété en elle-même, nous nous concentrons plutôt sur les valeurs de flex ou grid , cependant, il y a des choses intéressantes à comprendre sur display et sa définition qui vous faciliteront la vie lorsque vous l'utiliserez CSS pour la mise en page.

Dans cet article, le premier d'une courte série, je vais jeter un œil à la façon dont les valeurs d' display sont définies dans la spécification de niveau 3. Il s'agit d'un changement par rapport à la définition de display dans les versions antérieures de CSS. Bien que cela puisse sembler inhabituel au début pour 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 changeons la valeur d' display sur un élément.

Éléments de bloc et en ligne

L'une des premières choses que nous enseignons aux débutants en CSS sont les concepts d'éléments en bloc et en ligne. Nous expliquerons que certains éléments de la page sont display: block et qu'ils ont certaines fonctionnalités à cause de cela. Ils s'étendent dans le sens de l'alignement, occupant autant d'espace qu'il leur est disponible. Ils se brisent sur une nouvelle ligne; nous pouvons leur donner la largeur, la hauteur, la marge ainsi que le rembourrage, et ces propriétés éloigneront d'eux les autres éléments de la page.

On sait aussi que certains éléments sont display: inline . Les éléments en ligne sont comme des mots dans une phrase ; ils ne sautent pas sur une nouvelle ligne, mais réservent à la place un caractère d'espace blanc entre eux. Si vous ajoutez des marges et du rembourrage, cela s'affichera mais ne repoussera pas les autres éléments.

Le comportement des éléments de bloc et en ligne est fondamental pour CSS et le fait qu'un document HTML correctement balisé sera lisible par défaut. Cette mise en page est appelée "Block and Inline Layout" ou "Normal Flow" car c'est la façon dont les éléments se présentent si nous ne leur faisons rien d'autre.

Plus après saut! Continuez à lire ci-dessous ↓

Valeurs intérieures et extérieures de l' display

Nous comprenons les éléments en bloc et en ligne, mais que se passe-t-il si nous faisons en sorte qu'un élément display: grid ? Est-ce quelque chose de complètement différent ? Si nous regardons un composant sur lequel nous avons spécifié display: grid , en termes d'élément parent dans la mise en page, il se comporte comme un élément block level . L'élément s'étirera et occupera autant d'espace dans la dimension en ligne que disponible, il commencera sur une nouvelle ligne. Il se comporte comme un élément de block en termes de comportement avec le reste de la mise en page. Nous n'avons pas dit display: block cependant, ou l'avons-nous fait ?

Il s'avère que nous avons. Au niveau 3 de la spécification Display, la valeur de display est définie par deux mots-clés. Ces mots-clés définissent la valeur extérieure de display, qui sera inline ou block et définissent donc comment l'élément se comporte dans la mise en page aux côtés d'autres éléments. Ils définissent également la valeur interne de l'élément — ou comment les enfants directs de cet élément se comportent.

Cela signifie que lorsque vous dites display: grid , ce que vous dites en réalité est display: block grid . Vous demandez un conteneur de grille au niveau du bloc. Un élément qui aura tous les attributs de bloc - vous pouvez lui donner une hauteur et une largeur, une marge et un rembourrage, et il s'étirera pour remplir le conteneur. Les enfants de ce conteneur, cependant, ont reçu la valeur interne de grid afin qu'ils deviennent des éléments de grille. Le comportement de ces éléments de grille est défini dans la spécification de grille CSS : la spécification display nous donne un moyen d'indiquer au navigateur qu'il s'agit de la méthode de mise en page que nous voulons utiliser.

Je pense que cette façon de penser à display est incroyablement utile ; il explique directement ce que nous faisons avec diverses méthodes de mise en page. Si vous deviez spécifier display: inline flex , à quoi vous attendriez-vous ? Avec un peu de chance, une boîte qui se comporte comme un élément en ligne, avec des enfants qui sont des éléments flexibles.

Il y a quelques autres choses parfaitement expliquées en pensant à display de cette nouvelle manière, et j'examinerai certaines d'entre elles dans le reste de cet article.

Nous revenons toujours au flux normal

Lorsque l'on pense à ces propriétés d'affichage internes et externes, il peut être utile de considérer ce qui se passe si nous ne manions pas du tout avec la valeur de l'affichage. Si vous écrivez du code HTML et que vous l'affichez dans un navigateur, vous obtenez une mise en page en bloc et en ligne, ou un flux normal. Les éléments s'affichent sous forme de block ou d'éléments inline .

Voir le Pen Block et la mise en page en ligne par Rachel Andrew.

Voir le Pen Block et la mise en page en ligne par Rachel Andrew.

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

Voir Pen Block et Inline Layout With Flex Component par Rachel Andrew.

Voir Pen Block et Inline Layout With Flex Component par Rachel Andrew.

Si vous travaillez avec ce processus, le fait que les éléments de votre page se présentent avec cette belle mise en page de flux normale lisible, plutôt que de lutter contre et d'essayer de tout placer, CSS est beaucoup plus facile. Vous êtes également moins susceptible de tomber dans des problèmes d'accessibilité, car vous travaillez avec l'ordre des documents, ce qui est exactement ce que fait un lecteur d'écran ou une personne qui parcourt le document.

Expliquer flow-root et inline-block

La valeur de inline-block est également susceptible d'être familière à beaucoup d'entre nous qui font du CSS depuis un certain temps. Cette valeur est un moyen d'obtenir une partie du comportement 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 B lock F ormatting C ontent (BFC).

Un BFC fait des choses utiles en termes de mise en page, par exemple, il contient des flottants. Pour en savoir plus sur les contextes de formatage de bloc, consultez mon article précédent "Comprendre la disposition CSS et le contexte de formatage de bloc". Par conséquent, dire display: inline-block vous donne une boîte en ligne qui établit également un BFC.

Comme vous le découvrirez (si vous lisez l'article mentionné ci-dessus sur le contexte de formatage des blocs), il existe une nouvelle valeur d'affichage qui crée également explicitement un BFC. Il s'agit de la valeur de flow-root . Cette valeur crée un BFC sur un bloc, plutôt qu'un élément en ligne.

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

Vous pensez probablement maintenant que tout cela est un peu déroutant : 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 ? Cela mène parfaitement à la prochaine chose que je dois expliquer à propos de display , c'est-à-dire le fait que CSS a une histoire dont nous devons nous occuper en termes de propriété display .

Valeurs héritées de l'affichage

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

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

Les différentes propriétés internes de la table telles que table-cell dont nous ne traitons pas dans cet article ont également été définies.

Nous avons ensuite ajouté à ces quelques valeurs pour l'affichage, afin de prendre en charge la mise en page flexible et en grille :

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

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

Ce sont toutes des valeurs uniques pour la propriété display , définies avant la mise à jour de la spécification pour expliquer la mise en page CSS de cette manière. Quelque chose de très important à propos de CSS est le fait que nous n'allons pas casser le Web ; nous ne pouvons pas simplement changer les choses . Nous ne pouvons pas décider soudainement que tout le monde devrait utiliser cette nouvelle syntaxe à deux valeurs et, par conséquent, chaque site Web jamais construit qui utilisait la syntaxe à valeur unique tombera en panne à moins qu'un développeur ne revienne et ne le corrige !

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 le futur ! Cependant, le fait est que nous ne pouvons pas casser le Web, c'est pourquoi nous avons cette situation où les navigateurs prennent actuellement en charge un ensemble de valeurs uniques pour l'affichage, et la spécification passe à deux valeurs pour l'affichage.

La façon de contourner ce problème consiste à spécifier des valeurs héritées et courtes pour l'affichage, qui incluent toutes ces valeurs uniques. Cela signifie qu'un mappage peut être défini entre des valeurs uniques et deux nouvelles valeurs de mots-clés. Ce qui nous donne le tableau de valeurs suivant :

Valeur unique Valeurs à deux mots clés La description
block block flow Boîte de bloc avec intérieur à flux normal
flow-root block flow-root Boîte de bloc définissant un BFC
inline inline flow Boîte en ligne avec intérieur à flux normal
inline-block inline flow-root Boîte en ligne définissant un BFC
list-item block flow list-item Boîte de bloc avec intérieur à flux normal et boîte de marqueur supplémentaire
flex block flex Boîte de bloc avec disposition intérieure flexible
inline-flex inline flex Boîte en ligne avec disposition intérieure flexible
grid block grid Boîte de bloc avec disposition de grille intérieure
inline-grid inline grid Boîte en ligne avec disposition en grille intérieure
table block table Boîte de bloc avec disposition de table intérieure
inline-table inline table Boîte en ligne avec disposition de table interne

Pour expliquer comment cela fonctionne, nous pouvons penser à un conteneur de grille. Dans le monde à deux valeurs, nous créerions un conteneur de grille au niveau du bloc avec :

 .container { display: block grid; }

Cependant, le mot clé legacy signifie que ce qui suit 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 si vous utilisez les anciennes valeurs :

 .container { display: inline-grid; }

Nous pouvons maintenant revenir là où cette conversation a commencé et regarder display: inline-block . En regardant le tableau, vous pouvez voir que ceci 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 le souhaitez.

Prise en charge du navigateur pour la syntaxe à deux valeurs

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. La mise en œuvre, le cas échéant, impliquerait essentiellement l'aliasing des valeurs héritées vers les versions à deux valeurs. Par conséquent, il vous faudra probablement un bon moment avant de pouvoir réellement utiliser ces versions à deux valeurs dans votre code. Cependant, ce n'est vraiment pas le but de cet article. Au lieu de cela, je pense que regarder les valeurs d'affichage à la lumière du modèle à deux valeurs aide à expliquer une grande partie de ce qui se passe.

Lorsque vous définissez la mise en page sur 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 cela vous aidera à comprendre ce qui se passe lorsque vous modifiez la valeur de display .