Cours CSS / Flexbox : alignement, retour à la ligne et dimensions

Flexbox combine alignement, retour à la ligne et dimension flexible pour adapter les éléments à l'espace disponible. justify-content fonctionne sur l'axe principal, align-items agit sur l’axe transversal, et align-content distribue plusieurs lignes lorsqu'il y a de l'espace sur l'axe transversal à distribuer.

Associez les propriétés d'alignement à leurs axes

Propriété Applicable à Conditions à vérifier
justify-content Distribution des éléments le long de l'axe principal du conteneur Espace restant après définition de la taille de l'élément
align-items Alignement sur l’axe transversal de chaque élément Taille sur l’axe transversal de l'élément et hauteur de ligne
align-self Alignement sur l’axe transversal d'éléments spécifiques Modifier individuellement l'alignement par défaut du conteneur
align-content Alignement du groupe de lignes Conteneurs pouvant se répartir sur plusieurs lignes et espace restant sur l’axe transversal
gap Espacement entre les éléments/lignes adjacents Espace et division ajoutés par l'alignement

Dans une ligne, justify-content contrôle principalement l'horizontale, et align-items contrôle principalement la verticale. Si vous le changez en colonne, l'axe principal devient vertical et la direction physique des deux propriétés change également. En particulier, il doit y avoir de l'espace dans la hauteur du conteneur pour comparer le justify-content des colonnes. Si la hauteur correspond parfaitement au contenu, il y a presque aucun espace pour se déplacer même si vous choisissez center ou space-between. La direction de l'axe et le réglage de départ du conteneur Flex peuvent être vérifiés dans Les bases de Flexbox : conteneur, éléments et axes .

justify-content: center place un groupe d'éléments au centre, et space-between place le premier et le dernier élément aux deux extrémités et divise l'espace entre eux. gap est l'espace spécifié, et space-between distribue l'espace restant. Lorsqu'ils sont utilisés ensemble, l'écart réel peut être plus grand que le gap. Si le flex-grow d'un élément utilise tout l'espace restant ou si la marge automatique dans la direction de l'axe principal prend de l'espace, le changement de justify-content peut ne pas être visible.

align-items: center aligne les éléments de différentes hauteurs au centre sur une seule ligne. align-content: center centre toutes les lignes sur l'axe transversal. Vous ne devez pas considérer les deux comme la même fonction. align-content n'a aucun effet sur les conteneurs à une seule ligne avec nowrap, et même dans les conteneurs avec wrap, si la taille occupée par les lignes et la hauteur du conteneur sont identiques, il n'y a pas de marge pour la comparaison. Vous pouvez vérifier les conditions d'application dans le guide d'alignement Flexbox de MDN.

Comparer l'alignement des éléments et l'alignement des lignes

Enregistrez le code ci-dessous sous flex-align.html et ouvrez-le. La première section comporte trois éléments de hauteurs différentes, la deuxième section comporte quatre éléments en deux rangées. Dans la deuxième section, la hauteur de 280px réserve de l’espace pour déplacer le groupe de lignes.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-align.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.toolbar { display: flex; gap: 12px; justify-content: space-between; align-items: center;
 width: 100%; max-width: 640px; min-height: 120px; border: 2px solid #789; padding: 12px; }
 .toolbar > div { padding: 8px; background: #dceefa; }
 .lines { display: flex; flex-wrap: wrap; gap: 12px; width: min(100%, 360px); height: 280px;
 align-items: center; align-content: flex-start; border: 2px solid #789; padding: 12px; }
 .lines > div { flex: 0 0 140px; padding: 8px; background: #e8f5de; }
 .tall { min-height: 60px; }
  </style>
</head>
<body>
<h1>Alignment on one line and multiple lines</h1>
<h2>Toolbar</h2><div class="toolbar"><div>Short item</div><div>Two-line item<br>Second line</div><div>Button position</div></div>
<h2>Line group</h2><div class="lines"><div>1</div><div class="tall">2<br>Second line</div><div>3</div><div class="tall">4<br>Second line</div></div>
</body>
</html>
  1. Changez le justify-content de .toolbar en center pour voir si les trois éléments se regroupent au centre. Nous comparons également avec flex-start et revenons ensuite à space-between. Laissez la taille des éléments et l'espacement tels quels.
  2. Changez align-items dans .toolbar en flex-start pour vous assurer qu'ils s'alignent en haut. Si vous le changez en stretch, les éléments avec une taille automatique de l’axe transversal augmenteront. Après comparaison, il est rétabli à center.
  3. Remplacez uniquement align-content: flex-start par align-content: center dans .lines. Un ensemble de deux lignes descend tout en maintenant les relations des éléments de chaque ligne. Si vous revenez à flex-start et ne changez que align-items sur flex-start, la position des petits éléments de chaque ligne changera.
  4. Si vous changez simplement le flex-wrap de .lines en nowrap, tout essaiera de rester sur une seule ligne, et cet exemple a le rétrécissement désactivé par flex-shrink: 0, ce qui provoque un débordement horizontal. Dans cet état, vous ne pouvez pas aligner plusieurs lignes avec align-content. Après confirmation, rétablissez wrap.

Comprenez grow, shrink et basis

flex: 1 1 192px est croissance, rétrécissement et base dans cet ordre. La base est la taille standard à partir de laquelle commencer la répartition spatiale de l'axe principal et n'est pas une valeur qui garantit la largeur finale. La croissance est le taux d'agrandissement pour l'espace restant, et le rétrécissement est le taux de réduction lorsque l'espace est insuffisant. Comme il existe une règle de valeur omise pour les nombres simples ou auto dans les raccourcis, trois valeurs sont spécifiées et comparées dans l'exemple d'apprentissage.

déclaration Lorsqu'il reste de l'espace Lorsque l'espace est épuisé
flex: 0 1 192px Maintenir la taille standard Participer à la réduction
flex: 1 1 192px L'espace restant est réparti Participer à la réduction
flex: 0 0 192px Maintenir la taille standard Pas de réduction. S'il est en nowrap, il peut déborder.

Par exemple, si un parent avec une largeur de contenu de 640px contient trois éléments de taille de base 100px et deux espaces (chacun de 20px), l'espace restant est de 640 − 300 − 40 = 300px. Si le ratio de croissance est de 1:2:1, l'espace ajouté sera de 75px, 150px et 75px, et la largeur finale sera de 175px, 250px et 175px. C'est un calcul des conditions qui n'impliquent pas la taille minimale du contenu ou les contraintes min/max.

La quantité de rétrécissement n'est pas répartie de manière uniforme en se basant uniquement sur le nombre de rétrécissement. Prenez en compte à la fois le ratio de réduction et la taille de référence. Si nous devons réduire de 60px deux éléments avec des tailles standard de 200px et 100px et que les deux ont un rétrécissement de 1, alors dans des conditions simples sans contraintes, nous réduirions de 40px et 20px. Les résultats peuvent varier s'il y a des paddings, des bordures, une taille minimale du contenu, etc., donc vous devriez réellement vérifier les valeurs appliquées. La description du flex de MDN explique le raccourci et les conditions de taille.

Répartir l'espace et faire passer les cartes à la ligne

Enregistrez le code suivant sous flex-size.html. La zone de calcul correspond au calcul ci-dessus en créant une largeur maximale de 640px sans aucun remplissage ou bordure supplémentaire. La liste de cartes utilise une largeur de 192px comme standard pour les sauts de ligne, mais remplit l'espace restant. Si une liste avec list-style: none se trouve à l'extérieur de nav, elle peut ne pas être reconnue comme une liste dans l'arbre d'accessibilité de Safari. Dans l'exemple, ul spécifie role="list" pour indiquer le rôle de la liste. Les conditions d'accessibilité lors de la suppression des puces et de l'espacement sont également décrites dans Mise en forme des paragraphes et des listes en CSS.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-size.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.calc { display: flex; gap: 20px; width: min(100%, 640px); background: #eef2f6; }
 .calc > div { flex: 1 1 100px; min-width: 0; height: 80px; background: #dceefa; }
 .calc > div:nth-child(2) { flex-grow: 2; }
 .cards { display: flex; flex-wrap: wrap; gap: 16px; list-style: none; padding: 0; }
 .cards > li { flex: 1 1 192px; min-width: 0; padding: 16px; background: #e8f5de; overflow-wrap: anywhere; }
  </style>
</head>
<body>
<h1>Flex values ​​and space distribution</h1><div class="calc"><div>grow 1</div><div>grow 2</div><div>grow 1</div></div>
<h2>Wrapping card</h2><ul class="cards" role="list"><li>First card</li><li>Second card</li><li>Third card</li><li>Fourth card</li></ul>
</body>
</html>
  1. Agrandissez votre navigateur afin que le .calc fasse 640px de large et utilisez les outils de développement pour vérifier les largeurs des trois éléments. Elles seront de 175px·250px·175px. Si vous changez uniquement le grow du deuxième élément à 1, les trois éléments deviendront chacun 200px. Après comparaison, rétablissez-le à 2.
  2. Il suffit de changer le grow dans .cards > li à 0 pour s'assurer que la dernière rangée de cartes ne remplisse pas la largeur supplémentaire. Si vous le rétablissez à 1, la dernière ligne recevra également de l'espace.
  3. Réduisez l'écran pour voir si moins de cartes tiennent sur une ligne. wrap détermine quelles lignes placer, et chaque ligne distribue séparément l'espace restant. Les largeurs des cartes de la dernière ligne et de la ligne précédente ne correspondent pas nécessairement.
  4. Pour observer un débordement sur une seule ligne, remplacez flex-wrap: wrap par flex-wrap: nowrap dans .cards et appliquez flex: 0 0 192px à .cards > li. Après avoir vérifié les deux conditions, rétablissez le wrap d'origine et 1 1 192px.

Vérifier la taille minimale automatique et le texte long

La largeur minimale automatique d’un élément flex peut empêcher une zone contenant un identifiant long de rétrécir. min-width: 0 autorise la boîte à devenir plus étroite ; overflow-wrap: anywhere permet à la chaîne elle-même de passer à la ligne. Ces règles résolvent deux aspects différents du problème : rétrécir la boîte ne suffit pas à couper une chaîne longue. Consultez aussi le cours sur overflow et retour à la ligne.

Enregistrez le code ci-dessous sous flex-long-text.html. L’exemple contient un identifiant fictif sans espaces, et non une adresse réelle. Même si l'écran est rétréci, le texte à côté de la zone de guidage se lit divisé en plusieurs lignes. Vous pouvez vérifier les règles de retour à la ligne dans la description overflow-wrap de MDN.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>flex-long-text.html</title>
  <style>
* { box-sizing: border-box; }
body { margin: 16px; font: 16px/1.6 sans-serif; color: #243447; }
h1 { font-size: 24px; } h2 { font-size: 20px; margin-top: 32px; }
a { color: #145f8f; } a:focus-visible { outline: 3px solid #b4470b; outline-offset: 3px; }
.notice { display: flex; gap: 12px; max-width: 600px; border: 2px solid #789; padding: 12px; }
 .icon { flex: 0 0 48px; background: #ffe4b5; }
 .text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; background: #dceefa; }
 .text p { margin: 0; }
  </style>
</head>
<body>
<h1>Long strings and minimum sizes</h1><div class="notice"><div class="icon">Notice</div><div class="text"><p>ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</p></div></div>
</body>
</html>
  1. Dans .text, changez simplement overflow-wrap en normal. Même si la largeur de l’élément est réduite, la chaîne peut déborder hors des limites. Rétablissez overflow-wrap: anywhere.
  2. Pour voir l’impact de min-width séparément, supprimez min-width: 0 tout en maintenant overflow-wrap: normal. Après avoir déterminé comment la taille minimale des longues chaînes affecte le placement des éléments, nous restaurons les deux déclarations à leurs valeurs originales.

Si l'alignement n'est pas possible, vérifiez d'abord l'axe du parent et l'espace restant. Si la taille ne diminue pas, vérifiez la taille minimale de l'élément et la chaîne interne. Si vous mettez overflow: hidden sur l'ensemble du parent pour masquer le problème, vous risquez de perdre du contenu ou l'indication de focus. Il est plus facile de juger les résultats si la taille de la mise en page et l'affichage du contenu sont résolus séparément.