Flexbox

Podcast CSS – 010: Flexbox

Un modèle de conception qui peut être délicat dans le responsive design est la barre latérale qui s'intègre à certains contenus. Là où il y a de la fenêtre d'affichage, ce modèle fonctionne très bien, mais lorsque l'espace est condensé, cette mise en page rigide peut devenir problématique.

Le modèle de mise en page flexible (Flexbox) est un modèle de mise en page conçu pour du contenu unidimensionnel. 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 d'aligner la barre latérale et le contenu de manière intégrée, mais également d'intégrer la barre latérale si l'espace disponible est insuffisant. Au lieu de définir des dimensions rigides que le navigateur doit respecter, avec Flexbox, vous pouvez indiquer des limites flexibles pour indiquer comment le contenu peut s'afficher.

Que pouvez-vous faire avec une mise en page flexible ?

Les mises en page Flex offrent les fonctionnalités suivantes, que vous découvrirez dans ce guide.

  • Elles peuvent s'afficher sous la forme d'une ligne ou d'une colonne.
  • Ils respectent le mode d'écriture du document.
  • Il s'agit d'une seule ligne par défaut, mais il peut être demandé de s'encapsuler sur plusieurs lignes.
  • Les éléments de la mise en page peuvent être réorganisés visuellement, loin de leur ordre dans le DOM.
  • L'espace peut être réparti à l'intérieur des éléments. Ceux-ci deviennent plus grands en fonction de l'espace disponible dans l'élément 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 de l'alignement de la case.
  • Les éléments eux-mêmes peuvent être alignés sur l'axe transversal.

L'axe principal et l'axe transversal

Pour comprendre le 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 la valeur est row, votre axe principal se trouve le long de la ligne, et si la valeur est column, votre axe principal se trouve le long de la colonne.

Trois cases l'une à côté de l'autre avec une flèche pointant de gauche à droite. La flèche est intitulée Main Axe (Axe principal)

Les éléments Flex se déplacent en tant que groupe sur l'axe principal. N'oubliez pas: nous avons un tas de choses et nous essayons d'obtenir la meilleure mise en page pour elles en tant que 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 s'étend le long de la colonne.

Trois cases de hauteurs différentes, l'une à côté de l'autre par une flèche orientée de gauche à droite. La flèche est intitulée "Main Axe" (Axe principal). Une autre flèche pointe de haut en bas. Celle-ci est intitulée

Vous pouvez faire deux choses sur l'axe transversal. Vous pouvez déplacer les éléments individuellement ou de manière groupée afin qu'ils s'alignent les uns par rapport aux autres et au conteneur flexible. De plus, si vous avez des lignes flexibles encapsulées, vous pouvez les traiter comme un groupe pour contrôler la façon dont l'espace leur est attribué. Vous verrez comment tout cela fonctionne en pratique tout au long de ce guide. Pour l'instant, n'oubliez pas que l'axe principal suit votre flex-direction.

Créer un conteneur flexible

Voyons le comportement de Flexbox en prenant un groupe d'éléments de différentes tailles et en utilisant Flexbox pour les disposer.

<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 flexible, et non une mise en page standard et une mise en page intégrée. 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, vous obtenez une zone au niveau du bloc, avec des éléments enfants. Un certain comportement est immédiatement appliqué aux éléments Flexbox, à l'aide de leurs valeurs initiales.

Les valeurs initiales signifient que:

  • Les articles s'affichent sur une ligne.
  • Ils ne s'encapsulent pas.
  • Elles ne poussent pas pour remplir le conteneur.
  • Ils sont alignés 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 voulez une ligne, vous n'avez pas besoin d'ajouter la propriété. Pour changer de 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 en partant de la fin du conteneur flexible.
  • column: les éléments sont disposés sous forme de colonne.
  • column-reverse : les éléments sont disposés sous la forme d'une colonne à partir de la fin du conteneur flexible.

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

Inverser la circulation des éléments et l'accessibilité

Soyez prudent lorsque vous utilisez des propriétés qui éloignent l'affichage visuel de l'ordre des éléments 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, et non l’ordre logique. Il est important de le comprendre, car l'ordre logique correspond à l'ordre dans lequel un lecteur d'écran lira le contenu à voix haute, et toute personne naviguant à l'aide du clavier suivra.

Dans la vidéo suivante, vous pouvez voir comment, dans une mise en page en lignes inversées, la tabulation entre les liens se déconnecte lorsque la navigation au clavier suit le DOM et non l'affichage visuel.

Ce problème peut être dû à tout ce qui peut modifier l'ordre des éléments dans Flexbox ou grille. Par conséquent, toute réorganisation doit inclure des tests approfondis afin de vérifier qu'elle ne complique pas l'utilisation de votre site pour certaines personnes.

Pour en savoir plus, consultez la page suivante :

Modes et direction d'écriture

Par défaut, les éléments Flex sont présentés sous forme de ligne. Une ligne s'exécute dans le sens où les phrases circulent dans votre mode d'écriture et dans la direction du script. Cela signifie que si vous travaillez en arabe, qui se lit de droite à gauche (rtl), les éléments s'aligneront sur la droite. L'ordre de tabulation commencera également sur la droite, car c'est ainsi que les phrases sont lues en arabe.

Si vous utilisez un mode d'écriture vertical, comme certaines polices de caractères japonaises, une ligne s'affichera verticalement, de haut en bas. Essayez de modifier flex-direction dans cette démonstration en utilisant un mode d'écriture verticale.

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 écrits en anglais ou dans un autre mode d'écriture horizontal, de gauche à droite. Ainsi, il est facile de supposer que les éléments Flex s'alignent sur la gauche et s'exécutent horizontalement.

Avec l'axe principal et l'axe transversal, ainsi que le mode d'écriture à prendre en compte, le fait de parler de start et de end plutôt que de haut, de bas, de gauche et de droite dans Flexbox peut être plus facile à comprendre. Chaque axe a un début et une fin. Le début de l'axe principal est appelé main-start. Nos éléments flexibles sont donc initialement alignés à partir du début principal. L'extrémité de cet axe est main-end. Le début de l'axe transversal est cross-end (début de l'axe transversal) et le début de l'axe transversal (cross-end).

Un diagramme étiqueté des termes ci-dessus

Encapsuler des éléments flexibles

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épasseront.

Conteneur flexible contenant neuf éléments. Les éléments sont réduits, de sorte qu&#39;un mot se trouve sur une ligne, mais il n&#39;y a pas assez de place pour les afficher côte à côte. Les éléments flexibles se sont donc étendus en dehors du conteneur.
Une fois qu'ils auront atteint la taille minimale du contenu, les éléments flexibles commenceront à dépasser de leur conteneur.

Les éléments qui s'affichent à l'aide des valeurs initiales seront réduits le plus possible, jusqu'à atteindre la taille min-content avant un débordement.

Pour encapsuler les éléments, ajoutez flex-wrap: wrap au conteneur flexible.

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

Lorsqu'un conteneur flexible est encapsulé, il crée plusieurs lignes flexibles. En termes de distribution de l'espace, chaque ligne agit comme un nouveau conteneur flexible. Par conséquent, si vous encapsulez des lignes, il n'est pas possible d'aligner un élément de la ligne 2 sur un élément de la ligne 1 au-dessus. C'est ce que signifie "Flexbox" qui est unidimensionnel. Vous pouvez contrôler l'alignement sur un axe, une ligne ou une colonne, mais pas les deux ensemble, comme c'est le cas dans la grille.

Le raccourci Flex-flow

Vous pouvez définir les propriétés flex-direction et flex-wrap à l'aide du raccourci flex-flow. Par exemple, pour définir flex-direction sur column et autoriser l'encapsulation des éléments:

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

Contrôler l'espace à l'intérieur des éléments Flex

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

  • flex-grow: 0: les éléments ne poussent pas.
  • flex-shrink: 1: la taille des éléments peut être inférieure à celle de leur flex-basis.
  • flex-basis: auto: la taille de base des éléments est auto.

Elle peut être représentée par la valeur du mot clé flex: initial. La propriété abrégée flex ou les termes longs flex-grow, flex-shrink et flex-basis sont appliqués aux enfants du conteneur flexible.

Pour faire augmenter les éléments, tout en permettant aux éléments volumineux de disposer de plus d'espace que les petits, utilisez flex:auto. Vous pouvez essayer en utilisant la démo ci-dessus. Les propriétés sont alors définies sur:

  • flex-grow: 1: les éléments peuvent dépasser flex-basis.
  • flex-shrink: 1: la taille des éléments peut être inférieure à leur valeur flex-basis.
  • flex-basis: auto: la taille de base des éléments est auto.

L'utilisation de flex: auto signifie que les éléments ont des tailles différentes, car l'espace partagé entre les éléments est partagé après la disposition de chaque élément en tant que taille de contenu maximale. Ainsi, un grand élément occupera 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émo.

Cela se décompresse comme suit:

  • flex-grow: 1: les éléments peuvent dépasser flex-basis.
  • flex-shrink: 1: la taille des éléments peut être inférieure à leur valeur 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 flexible peut être distribué. Comme tous les éléments ont un facteur flex-grow de 1, ils croissent tous de la même manière et l'espace est partagé de manière égale.

Permettre aux articles de se développer à des rythmes différents

Vous n'avez pas besoin d'attribuer un facteur flex-grow de 1 à tous les éléments. Vous pouvez attribuer différents facteurs flex-grow à vos éléments Flex. Dans la démonstration ci-dessous, le premier élément contient 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 flexible est partagé en six éléments. Une partie est attribuée au premier élément, deux parties au deuxième et trois parties au troisième.

Vous pouvez procéder de la même manière à partir d'un flex-basis de auto, mais vous devrez spécifier les trois valeurs. La première valeur est 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 l'utilisation d'une flex-basis de auto permet de permettre au navigateur de déterminer la répartition de l'espace. Si vous souhaitez qu'un élément se développe un peu plus que ce que l'algorithme décide, quelle que soit la façon dont il pourrait être utile.

Réorganisation des éléments Flex

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 dans des groupes ordinaux. Les éléments sont disposés dans la direction indiquée par flex-direction, en commençant par les valeurs les plus basses. Si plusieurs éléments ont la même valeur, il sera affiché avec les autres éléments associés à cette valeur.

L'exemple ci-dessous illustre cet ordre.

Testez vos connaissances

Tester vos connaissances sur Flexbox

La valeur flex-direction par défaut est

row
Par défaut, Flexbox place les éléments sur une ligne en les alignant au début. Lorsque l'encapsulation est activée, elle continue à créer des lignes dans lesquelles les enfants peuvent circuler.
column
Définir l'orientation flexible dans la colonne est un excellent moyen d'empiler des éléments, mais ce n'est pas la valeur par défaut.

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

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

Un élément enfant Flex semble écrasé. Quelle propriété flexible permet d'atténuer ce problème ?

flex-grow
Cette propriété indique si les éléments peuvent dépasser une taille de base, et non comment ils doivent se comporter sous une base.
flex-shrink
Oui, cette propriété décrit comment gérer le dimensionnement si la largeur passe en dessous de la base.
flex-basis
Il s'agit du point de départ du dimensionnement, mais il n'est pas possible de gérer les scénarios de dimensionnement dans lesquels la largeur passe en dessous de la base, comme dans le cas d'une réduction de la taille.

Présentation de l'alignement de Flexbox

Flexbox s'accompagne d'un ensemble de propriétés permettant d'aligner des é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 dans leur propre spécification que vous les rencontrerez également dans la mise en page sous forme de grille. Découvrez ici leur fonctionnement lorsque vous utilisez Flexbox.

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

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

Les propriétés utilisées pour l'alignement dans Flexbox sont les suivantes:

  • 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-. L'axe transversal commence par align-.

Distribuer de l'espace sur l'axe principal

Avec le code HTML utilisé précédemment, les éléments Flex disposés sous forme de ligne, il y a de l'espace sur l'axe principal. Les éléments 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 tout espace supplémentaire se trouve à la fin.

Ajoutez la propriété justify-content au conteneur flexible et attribuez-lui la valeur flex-end. Les éléments s'affichent à 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 avec justify-content: space-between.

Essayez certaines des valeurs de la démonstration et consultez MDN pour connaître 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 libre 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 pour le distribuer.

Testez les différentes valeurs, cette fois avec une mise en page de colonne Flexbox.

Répartir l'espace entre les lignes flexibles

Avec un conteneur flexible encapsulé, vous pouvez avoir de l'espace à répartir 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 flexible pour modifier ce comportement par défaut.

.container {
  align-content: center;
}

Essayez dans la démo. L'exemple contient des lignes d'éléments flexibles et le conteneur dispose d'un block-size afin de disposer d'un espace libre.

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 que la première sera 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 flexible à l'aide de align-items et align-self. L'espace disponible pour cet alignement dépend de la hauteur du conteneur flexible (ou de la ligne flexible dans le cas d'un ensemble d'éléments encapsulés).

La valeur initiale de align-self est stretch. C'est pourquoi les éléments flexibles d'une ligne s'étirent par défaut jusqu'à la hauteur de l'élément le plus grand. Pour modifier cela, ajoutez la propriété align-self à tous 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 Flex avec flex-direction: row. Le dernier élément définit la hauteur du conteneur flexible. Le premier élément a la propriété align-self avec la valeur 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 est appliquée aux éléments individuels. La propriété align-items peut être appliquée au conteneur flexible 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, 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 raisonnement dans Flexbox ?

Les éléments Flex agissent comme un groupe sur l'axe principal. Il n'y a donc pas de concept de division d'un article individuel de ce groupe.

Dans la mise en page en grille, les propriétés justify-self et justify-items fonctionnent sur l'axe intégré 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 comme un groupe, ces propriétés ne sont pas implémentées dans ce contexte.

Il est intéressant de noter que le 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. Dans l'exemple ci-dessous, la marge 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 pousse 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, à savoir 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 le Flexbox, utilisez

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

Pour aligner horizontalement sur 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 une taille de contenu pour les éléments enfants, lequel des styles suivants devez-vous utiliser ?

justify-content: flex-start
La propriété "justify" s'applique à l'alignement horizontal, et non à l'alignement vertical.
align-content: start
content aligne les lignes flexibles, 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 avec le "haut" ou le début, ce qui supprime la valeur d'étirement par défaut et utilise à la place la hauteur du contenu.

Ressources