Flexbox

The CSS Podcast - 010: Flexbox

Un modèle de conception qui peut être délicat dans le responsive design est une barre latérale qui est alignée avec certains contenus. Lorsque l'espace de la fenêtre d'affichage est suffisant, ce modèle fonctionne parfaitement, mais lorsque l'espace est réduit, cette mise en page rigide peut poser problème.

Flexbox est un modèle de mise en page conçu pour les contenus unidimensionnels. Il excelle à prendre un ensemble d'éléments de différentes tailles et à renvoyer la meilleure mise en page pour ces éléments.

Il s'agit du modèle de mise en page idéal pour ce modèle de barre latérale. Flexbox permet non seulement de disposer la barre latérale et le contenu de façon intégrée, mais aussi lorsqu'il ne reste pas assez d'espace disponible, la barre latérale s'affiche sur une nouvelle ligne. Au lieu de définir des dimensions rigides que le navigateur doit suivre, vous pouvez indiquer des limites flexibles afin d'indiquer comment le contenu pourrait s'afficher avec Flexbox.

À quoi sert une mise en page flexible ?

Les mises en page Flex présentent les fonctionnalités suivantes, que vous pourrez découvrir dans ce guide.

  • Elles peuvent s'afficher sous forme de ligne ou de colonne.
  • Elles respectent le mode d'écriture du document.
  • Elles sont une seule ligne par défaut, mais vous pouvez demander à encapsuler sur plusieurs lignes.
  • Les éléments de la mise en page peuvent être réorganisés visuellement, indépendamment de leur ordre dans le DOM.
  • L'espace peut être distribué à l'intérieur des éléments, de sorte qu'ils deviennent plus grands ou plus petits en fonction de l'espace disponible dans leur parent.
  • L'espace peut être réparti autour des éléments et des lignes flexibles dans une mise en page encapsulée à l'aide des propriétés d'alignement de boîte.
  • Les éléments eux-mêmes peuvent être alignés sur l'axe transversal.

Axe principal et axe transversal

Pour comprendre Flexbox, il est essentiel de comprendre le concept d'axe principal et d'axe transversal. L'axe principal est celui défini par votre propriété flex-direction. Si c'est row, votre axe principal se trouve le long de la ligne. S'il est column, votre axe principal se trouve le long de la colonne.

Trois rectangles l'un à côté de l'autre avec une flèche pointant de gauche à droite. La flèche est libellée "Axe principal".

Les éléments Flex se déplacent en groupe sur l'axe principal. N'oubliez pas que nous avons un tas de choses et que nous essayons de trouver la meilleure mise en page pour elles en groupe.

L'axe transversal s'étend dans l'autre sens par rapport à l'axe principal. Par conséquent, si flex-direction est défini sur row, l'axe transversal court le long de la colonne.

Trois rectangles de différentes hauteurs, côte à côte, avec une flèche pointant de gauche à droite. La flèche est libellée "Axe principal". Il y a une autre flèche 
pointant du haut vers le bas. Celui-ci est intitulé Axe transversal

Vous pouvez effectuer deux actions sur l'axe transversal. Vous pouvez déplacer les éléments individuellement ou en groupe afin qu'ils s'alignent les uns sur les autres et sur le conteneur flex. De plus, si vous avez enroulé des lignes flex, vous pouvez les traiter comme un groupe pour contrôler l'espace qui leur est attribué. Vous verrez comment tout cela fonctionne dans la pratique tout au long de ce guide. Pour l'instant, gardez à l'esprit que l'axe principal suit votre flex-direction.

Créer un conteneur flex

Voyons comment flexbox se comporte en prenant un groupe d'éléments de différentes tailles et en utilisant flexbox pour les mettre en page.

<div class="container" id="container">
  <div>One</div>
  <div>Item two</div>
  <div>The item we will refer to as three</div>
</div>

Pour utiliser Flexbox, vous devez déclarer que vous souhaitez utiliser un contexte de mise en forme flex et non une mise en page en ligne et en bloc standard. Pour ce faire, remplacez la valeur de la propriété display par flex.

.container {
  display: flex;
}

Comme vous l'avez appris dans le guide de mise en page, cela vous donne une zone au niveau du bloc, avec des enfants d'éléments flex. Les éléments flex commencent immédiatement à présenter un comportement de flexbox, en utilisant leurs valeurs initiales.

Les valeurs initiales signifient que :

  • Les éléments s'affichent sur une ligne.
  • Elles ne s'enroulent pas.
  • Elles ne se développent pas pour remplir le conteneur.
  • Elles s'alignent au début du conteneur.

Contrôler l'orientation des éléments

Même si vous n'avez pas encore ajouté de propriété flex-direction, les éléments s'affichent sous forme de ligne, car la valeur initiale de flex-direction est row. Si vous souhaitez une ligne, vous n'avez pas besoin d'ajouter la propriété. Pour modifier la direction, ajoutez la propriété et l'une des quatre valeurs suivantes :

  • row : les éléments sont disposés en ligne.
  • Avec row-reverse:, les éléments sont disposés sur une ligne à partir de l'extrémité du conteneur flexible.
  • column : les éléments sont disposés en colonne.
  • column-reverse : les éléments sont disposés en colonne à partir de la fin du conteneur Flex.

Vous pouvez essayer toutes les valeurs à l'aide de notre groupe d'articles dans la démonstration ci-dessous.

Inverser le flux d'éléments et l'accessibilité

Vous devez faire preuve de prudence lorsque vous utilisez des propriétés qui réorganisent l'affichage visuel de manière différente de l'ordre dans le document HTML, car cela peut avoir un impact négatif sur l'accessibilité. Les valeurs row-reverse et column-reverse en sont un bon exemple. La réorganisation ne se produit que pour l'ordre visuel, pas pour l'ordre logique. Il est important de comprendre cela, car c'est l'ordre logique que suivra un lecteur d'écran pour lire le contenu et que toute personne qui navigue à l'aide du clavier suivra.

La vidéo suivante montre comment, dans une mise en page en lignes inversées, la navigation par tabulation entre les liens est interrompue, car la navigation au clavier suit le DOM et non l'affichage visuel.

Tout élément pouvant modifier l'ordre des éléments dans une grille ou une flexbox peut entraîner ce problème. Par conséquent, toute réorganisation doit inclure des tests approfondis pour vérifier qu'elle ne rendra pas l'utilisation de votre site difficile pour certaines personnes.

Pour en savoir plus, consultez cette page :

Modes et orientation d'écriture

Par défaut, les éléments Flex sont disposés sur une ligne. Une ligne s'affiche dans le sens de la lecture des phrases dans votre mode d'écriture et le sens du script. Cela signifie que si vous travaillez en arabe, avec un script de droite à gauche (RTL), les éléments seront alignés à droite. L'ordre de tabulation commencerait également à droite, car c'est ainsi que les phrases sont lues en arabe.

Si vous utilisez un mode d'écriture vertical, comme certaines polices japonaises, une ligne s'affiche verticalement, de haut en bas. Essayez de modifier le flex-direction dans cette démonstration qui utilise un mode d'écriture vertical.

Par conséquent, le comportement par défaut des éléments Flex est lié au mode d'écriture du document. La plupart des tutoriels sont rédigés en anglais ou dans une autre langue s'écrivant de gauche à droite. Il serait ainsi facile de supposer que les éléments Flex sont alignés à gauche et s'exécutent horizontalement.

Avec l'axe principal et l'axe transversal, ainsi que le mode d'écriture à prendre en compte, il peut être plus facile de comprendre que nous parlons de début et de fin plutôt que de haut, de bas, de gauche et de droite dans flexbox. Chaque axe a un début et une fin. Le début de l'axe principal est appelé main-start. Nos éléments Flex s'alignent donc initialement à partir de "main-start". La fin de cet axe est main-end. Le début de l'axe transversal est cross-start et l'extrémité cross-end.

Schéma des termes ci-dessus avec libellés

Encapsuler des éléments flex

La valeur initiale de la propriété flex-wrap est nowrap. Cela signifie que si l'espace dans le conteneur est insuffisant, les éléments déborderont.

Conteneur flexible comportant neuf éléments, les éléments ont été réduits de sorte qu&#39;un mot se trouve sur une ligne, mais il n&#39;y a pas assez d&#39;espace pour les afficher côte à côte afin que les éléments flexibles soient étendus à l&#39;extérieur de la boîte du conteneur.
Une fois que la taille minimale du contenu est atteinte, les éléments Flex commencent à déborder de leur conteneur.

Les éléments affichés à l'aide des valeurs initiales seront réduits au maximum, jusqu'à la taille min-content avant le débordement.

Pour que les éléments soient mis en ligne, ajoutez flex-wrap: wrap au conteneur flex.

.container {
  display: flex;
  flex-wrap: wrap;
}

Lorsqu'un conteneur flex est encapsulé, il crée plusieurs lignes flex. En termes de distribution de l'espace, chaque ligne agit comme un nouveau conteneur flex. Par conséquent, si vous encapsulez des lignes, il n'est pas possible d'aligner un élément de la ligne 2 avec un élément situé au-dessus dans la ligne 1. C'est ce que l'on entend par "flexbox unidimensionnel". Vous pouvez contrôler l'alignement sur une seule des axes, une ligne ou une colonne, et non les deux à la fois comme vous pouvez le faire dans une grille.

Raccourci flex-flow

Vous pouvez définir les propriétés flex-direction et flex-wrap à l'aide de l'abréviation flex-flow. Par exemple, pour définir flex-direction sur column et permettre le retour à la ligne des éléments :

.container {
  display: flex;
  flex-flow: column wrap;
}

Contrôler l'espace dans les éléments Flex

En supposant que notre conteneur dispose de plus d'espace que nécessaire pour afficher les éléments, ceux-ci sont alignés au début et ne s'agrandissent pas pour occuper l'espace. Ils cessent de croître à la taille maximale de leur contenu. En effet, la valeur initiale des propriétés flex- est la suivante:

  • flex-grow: 0 : les éléments ne se développent pas.
  • flex-shrink: 1 : les éléments peuvent être réduits à une taille inférieure à leur flex-basis.
  • flex-basis: auto : la taille de base des éléments est auto.

Cela peut être représenté par une valeur de mot clé flex: initial. La propriété abrégée flex ou les valeurs longues de flex-grow, flex-shrink et flex-basis sont appliquées aux enfants du conteneur flex.

Pour que les éléments se développent, tout en permettant aux éléments volumineux d'avoir plus d'espace que les petits, utilisez flex:auto. Vous pouvez essayer cela à l'aide de la démonstration ci-dessus. Cela définit les propriétés sur:

  • flex-grow: 1 : les éléments peuvent être plus grands que leur flex-basis.
  • flex-shrink: 1 : les éléments peuvent être réduits à une taille inférieure à leur flex-basis.
  • flex-basis: auto : la taille de base des éléments est auto.

L'utilisation de flex: auto signifie que les éléments se retrouvent des tailles différentes, car l'espace partagé entre les éléments est partagé après que chaque élément a été défini en tant que taille maximale du contenu. Un article volumineux gagnera donc plus d'espace. Pour forcer tous les éléments à avoir une taille cohérente et ignorer la taille du contenu, remplacez flex:auto par flex: 1 dans la démonstration.

Cette opération se décompose comme suit :

  • flex-grow: 1 : les éléments peuvent être plus grands que leur flex-basis.
  • flex-shrink: 1 : les éléments peuvent être réduits à une taille inférieure à leur flex-basis.
  • flex-basis: 0 : la taille de base des éléments est 0.

L'utilisation de flex: 1 indique que tous les éléments ont une taille nulle. Par conséquent, tout l'espace du conteneur Flex peut être distribué. Étant donné que tous les éléments ont un facteur flex-grow de 1, ils se développent tous de manière égale et l'espace est partagé de manière égale.

Permettre une croissance des éléments à des rythmes différents

Il n'est pas nécessaire de définir un facteur flex-grow de 1 pour tous les éléments. Vous pouvez définir différents facteurs flex-grow pour vos articles modulables. Dans la démonstration ci-dessous, le premier élément comporte flex: 1, le deuxième flex: 2 et le troisième flex: 3. À mesure que ces éléments passent de 0, l'espace disponible dans le conteneur Flex est divisé en six. Une partie est attribuée au premier élément, deux au deuxième et trois au troisième.

Vous pouvez faire la même chose à partir d'un flex-basis de auto, mais vous devrez spécifier les trois valeurs. La première valeur étant flex-grow, la deuxième flex-shrink et la troisième flex-basis.

.item1 {
  flex: 1 1 auto;
}

.item2 {
  flex: 2 1 auto;
}

Ce cas d'utilisation est moins courant, car une flex-basis de auto permet au navigateur de déterminer la répartition de l'espace. Toutefois, si vous souhaitez que l'algorithme fasse croître un élément un peu plus que ce qu'il décide, cela peut être utile.

Réorganisation d'articles flexibles

Vous pouvez réorganiser les éléments de votre conteneur flex à l'aide de la propriété order. Cette propriété permet d'organiser les éléments en groupes ordonnés. Les éléments sont disposés dans la direction dictée par flex-direction, les valeurs les plus basses en premier. Si plusieurs éléments ont la même valeur, ils s'affichent ensemble.

L'exemple ci-dessous illustre ce tri.

Vérifier vos connaissances

Tester vos connaissances sur Flexbox

La valeur flex-direction par défaut est

row
Par défaut, Flexbox adapte les éléments à une ligne, en les alignant au début. Lorsque le forçage de ligne est activé, des lignes continuent d'être créées pour que les enfants puissent s'y insérer.
column
Définir flex-direction sur "column" est un excellent moyen d'empiler des éléments, mais ce n'est pas la valeur par défaut.

Par défaut, un conteneur Flex encapsule les enfants.

true
L'enveloppement doit être activé.
faux
Utiliser flex-wrap: wrap avec display: flex pour encapsuler les enfants

Un élément enfant flex semble écrasé. Quelle propriété flex permet de l'atténuer ?

flex-grow
Cette propriété indique si les éléments peuvent dépasser une taille de base, et non comment ils doivent se comporter en dessous d'une base.
flex-shrink
Oui, cette propriété décrit comment gérer la mise à l'échelle si la largeur est inférieure à la base.
flex-basis
Cela fournit le point de départ de la mise à l'échelle, mais pas la façon de gérer les scénarios de mise à l'échelle où la largeur est inférieure à la base, comme dans un scénario écrasé.

Présentation de l'alignement Flexbox

Flexbox a apporté un ensemble de propriétés permettant d'aligner les éléments et de répartir l'espace entre eux. Ces propriétés étaient si utiles qu'elles ont depuis été déplacées vers leur propre spécification. Vous les trouverez également dans la mise en page en grille. Découvrez ici comment ils fonctionnent lorsque vous utilisez Flexbox.

L'ensemble des établissements peut être placé dans deux groupes. Propriétés de distribution de l'espace et propriétés d'alignement. Les propriétés qui distribuent l'espace sont les suivantes :

  • justify-content : distribution de l'espace sur l'axe principal.
  • align-content : distribution de l'espace sur l'axe transversal.
  • place-content : raccourci permettant de définir les deux propriétés ci-dessus.

Propriétés utilisées pour l'alignement dans Flexbox :

  • align-self : aligne un seul élément sur l'axe transversal.
  • align-items: aligne tous les éléments en tant que groupe sur l'axe transversal.

Si vous travaillez sur l'axe principal, les propriétés commencent par justify-. Sur l'axe transversal, ils commencent par align-.

Répartition de l'espace sur l'axe principal

Avec le code HTML utilisé précédemment, les éléments Flex disposés en ligne, il y a de l'espace sur l'axe principal. Les articles ne sont pas assez grands pour remplir complètement le conteneur flexible. Les éléments sont alignés au début du conteneur flexible, car la valeur initiale de justify-content est flex-start. Les éléments sont alignés au début, et les espaces supplémentaires se trouvent à la fin.

Ajoutez la propriété justify-content au conteneur flexible et attribuez-lui la valeur flex-end. Les éléments sont alignés à la fin du conteneur et l'espace libre est placé au début.

.container {
  display: flex;
  justify-content: flex-end;
}

Vous pouvez également répartir l'espace entre les éléments à l'aide de justify-content: space-between.

Essayez certaines des valeurs de la démonstration et consultez la documentation MDN pour obtenir l'ensemble complet des valeurs possibles.

Avec flex-direction: column

Si vous avez remplacé votre flex-direction par column, justify-content fonctionnera sur la colonne. Pour disposer d'espace supplémentaire dans votre conteneur lorsque vous travaillez en tant que colonne, vous devez attribuer à votre conteneur un height ou un block-size. Sinon, vous n'aurez pas d'espace libre à distribuer.

Essayez les différentes valeurs, cette fois avec une mise en page en colonnes flexbox.

Répartir l'espace entre les lignes flexibles

Avec un conteneur flex enveloppé, vous pouvez avoir de l'espace à distribuer sur l'axe transversal. Dans ce cas, vous pouvez utiliser la propriété align-content avec les mêmes valeurs que justify-content. Contrairement à justify-content, qui aligne les éléments sur flex-start par défaut, la valeur initiale de align-content est stretch. Ajoutez la propriété align-content au conteneur flex pour modifier ce comportement par défaut.

.container {
  align-content: center;
}

Essayez-le dans la démonstration. L'exemple comporte des lignes de retour à la ligne d'éléments Flex, et le conteneur comporte un block-size afin de disposer d'espace supplémentaire.

Le raccourci place-content

Pour définir à la fois justify-content et align-content, vous pouvez utiliser place-content avec une ou deux valeurs. Une seule valeur sera utilisée pour les deux axes. Si vous spécifiez les deux, la première est utilisée pour align-content et la seconde pour justify-content.

.container {
  place-content: space-between;
  /* sets both to space-between */
}

.container {
  place-content: center flex-end;
  /* wrapped lines on the cross axis are centered,
  on the main axis items are aligned to the end of the flex container */
}

Aligner des éléments sur l'axe transversal

Sur l'axe transversal, vous pouvez également aligner vos éléments dans la ligne flex à l'aide de align-items et align-self. L'espace disponible pour cet alignement dépend de la hauteur du conteneur Flex ou de la ligne Flex dans le cas d'un ensemble d'éléments en ligne.

La valeur initiale de align-self est stretch. C'est pourquoi les éléments flex d'une ligne s'étendent jusqu'à la hauteur de l'élément le plus haut par défaut. Pour modifier cela, ajoutez la propriété align-self à l'un de vos éléments flex.

.container {
  display: flex;
}

.item1 {
  align-self: flex-start;
}

Utilisez l'une des valeurs suivantes pour aligner l'élément :

  • flex-start
  • flex-end
  • center
  • stretch
  • baseline

Consultez la liste complète des valeurs sur MDN.

La démonstration suivante comporte une seule ligne d'éléments flexibles avec flex-direction: row. Le dernier élément définit la hauteur du conteneur flex. Le premier élément possède la propriété align-self avec une valeur de flex-start. Essayez de modifier la valeur de cette propriété pour voir comment elle se déplace dans son espace sur l'axe transversal.

La propriété align-self s'applique à des éléments individuels. La propriété align-items peut être appliquée au conteneur flex pour définir toutes les propriétés align-self individuelles en tant que groupe.

.container {
  display: flex;
  align-items: flex-start;
}

Dans cette démonstration suivante, essayez de modifier la valeur de align-items pour aligner tous les éléments de l'axe transversal en tant que groupe.

Pourquoi n'y a-t-il pas de justification dans Flexbox ?

Les éléments Flex agissent comme un groupe sur l'axe principal. Il n'est donc pas possible de séparer un élément individuel de ce groupe.

Dans la mise en page en grille, les propriétés justify-self et justify-items fonctionnent sur l'axe en ligne pour aligner les éléments sur cet axe dans leur zone de grille. En raison de la façon dont les mises en page flex traitent les éléments en tant que groupe, ces propriétés ne sont pas implémentées dans un contexte flex.

Sachez que Flexbox fonctionne très bien avec les marges automatiques. Si vous avez besoin de séparer un élément d'un groupe ou de séparer le groupe en deux groupes, vous pouvez appliquer une marge pour ce faire. Dans l'exemple ci-dessous, la marge de gauche du dernier élément est de auto. La marge automatique absorbe tout l'espace dans la direction où elle est appliquée. Cela signifie qu'il déplace l'élément vers la droite, ce qui divise les groupes.

Centrer un élément verticalement et horizontalement

Les propriétés d'alignement peuvent être utilisées pour centrer un élément dans une autre zone. La propriété justify-content aligne l'élément sur l'axe principal, qui est la ligne. Propriété align-items sur l'axe transversal.

.container {
  width: 400px;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Testez vos connaissances

Tester vos connaissances sur Flexbox

.container {
  display: flex;
  direction: ltr;
}

Pour aligner verticalement avec Flexbox, utilisez

aligner les mots clés
Nice
justifier les mots clés
Désolé
.container {
  display: flex;
  direction: ltr;
}

Pour aligner horizontalement avec Flexbox, utilisez

aligner les mots clés
Désolé
justifier les mots clés
Nice
.container {
  display: flex;
  direction: ltr;
}

Par défaut, les éléments Flex sont alignés sur stretch. Si vous souhaitez utiliser la taille de contenu pour les éléments enfants, lequel des styles suivants utiliseriez-vous ?

justify-content: flex-start
La propriété justify est destinée à l'alignement horizontal, et non vertical.
align-content: start
content aligne les lignes flex, et non l'alignement des éléments enfants.
height: auto
Cela n'aura aucun effet.
align-items: flex-start
Oui, nous voulons les aligner verticalement en haut ou au début, ce qui supprime la valeur d'étirement par défaut et utilise plutôt la hauteur du contenu.

Ressources