Les flexbox

Description Sommaire

Dans ce chapitre, on va découvrir le principe des flexbox. C'est un mode de mise en page extrêmement pratique pour aligner des éléments, les espacer, les centrer ou répartir automatiquement l'espace disponible.

On l'a déjà croisé rapidement lorsqu'on a parlé de display, mais ici on va prendre le temps de voir comment il fonctionne réellement.

Ressources

Le principe des flexbox

Les flexbox permettent de changer la manière dont les éléments enfants d'un conteneur sont disposés.

Au lieu d'empiler les éléments comme avec le comportement normal des blocs, on définit un axe principal et les enfants vont s'aligner le long de cet axe.

Le principe de base est toujours le même :

  • on a un élément parent
  • ce parent contient plusieurs enfants
  • on applique display: flex au parent
.demo {
  display: flex;
}

À partir de là, les enfants se comportent différemment : au lieu de s'empiler, ils viennent se placer les uns à côté des autres.

Axe principal et axe secondaire

Quand on active un conteneur flex, il faut raisonner avec deux axes :

  • l'axe principal, le long duquel les éléments vont venir se placer
  • l'axe secondaire, perpendiculaire à l'axe principal il est utilisé pour gérer l'alignement.

Par défaut, l'axe principal va de gauche à droite. C'est donc le long de cet axe que les éléments vont se disposer.

La plupart des propriétés flexbox consistent ensuite à répondre à deux questions :

  • comment les éléments se placent-ils sur l'axe principal ?
  • comment se placent-ils sur l'axe secondaire ?

flex-direction

La propriété flex-direction permet de définir l'orientation de l'axe principal.

.demo {
  display: flex;
  flex-direction: row;
}

Les valeurs principales sont :

  • row : les éléments se placent en ligne, de gauche à droite
  • column : les éléments se placent en colonne, de haut en bas
  • row-reverse : les éléments se placent de droite à gauche
  • column-reverse : les éléments se placent de bas en haut

Ce point est fondamental, car toutes les autres propriétés dépendent de cet axe.

justify-content

justify-content permet de positionner les éléments le long de l'axe principal.

Par défaut, les éléments sont placés au début de l'axe.

.demo {
  display: flex;
  justify-content: center;
}

Les valeurs les plus utiles sont :

  • flex-start : au début de l'axe
  • flex-end : à la fin de l'axe
  • center : au centre
  • space-between : espace réparti entre les éléments
  • space-around : espace autour des éléments
  • space-evenly : espace uniforme partout

⚠️ Il faut bien retenir que justify-content suit toujours l'axe principal. Si flex-direction passe en column, justify-content agit alors verticalement.

align-items

align-items permet de positionner les éléments sur l'axe secondaire (l'axe perpendiculaire).

.demo {
  display: flex;
  align-items: center;
}

Les valeurs principales sont :

  • flex-start
  • flex-end
  • center
  • baseline
  • stretch
align-items: flex-start;
align-items: flex-end;
align-items: center;
align-items: baseline;
align-items: stretch;

Le cas de baseline

baseline aligne les éléments selon la ligne de base du texte. C'est surtout utile lorsque les éléments n'ont pas tous la même taille de police.

Le cas de stretch

stretch est la valeur par défaut. Elle fait en sorte que les enfants s'étirent pour occuper tout l'espace disponible sur l'axe secondaire. Cela ne fonctionne que si les enfants n'ont pas déjà une taille fixée sur cet axe.

Le retour à la ligne avec flex-wrap

Par défaut, un conteneur flex essaie de garder tous ses enfants sur une seule ligne.

.demo {
  display: flex;
  flex-wrap: nowrap;
}

La valeur par défaut est nowrap, ce qui signifie qu'en cas de manque de place, les éléments vont se rétrécir. Si on veut autoriser le retour à la ligne :

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

Les valeurs possibles sont :

  • nowrap
  • wrap
  • wrap-reverse
flex-wrap: nowrap;
flex-wrap: wrap;
flex-wrap: wrap-reverse;

wrap-reverse inverse simplement l'ordre visuel des lignes.

align-content

Quand flex-wrap crée plusieurs lignes, on peut contrôler la manière dont les lignes elles-mêmes se répartissent avec align-content.

.demo {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
}

Les valeurs sont très proches de celles de justify-content :

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • space-evenly

Attention à ne pas confondre :

  • align-items aligne les éléments dans une ligne
  • align-content aligne les lignes entre elles

Et comme toujours, l'effet dépend de l'orientation de l'axe.

gap

Pour créer de l'espace entre les éléments, on peut utiliser gap.

.demo {
  display: flex;
  gap: 20px;
}

Si on veut distinguer l'espace entre les lignes et celui entre les colonnes :

row-gap: 10px;
column-gap: 20px;

Et la forme raccourcie :

gap: 10px 20px;

Ici :

  • la première valeur correspond au row-gap
  • la seconde au column-gap

gap est souvent plus propre que de bricoler avec des marges sur les enfants.

Les raccourcis du conteneur

Comme souvent en CSS, il existe des propriétés raccourcies.

Par exemple :

flex-flow: row wrap;

Cette propriété combine :

  • flex-direction
  • flex-wrap

Les propriétés appliquées aux enfants

Jusqu'ici, on a vu les propriétés du conteneur. Mais les enfants flex peuvent eux aussi avoir des réglages spécifiques.

align-self

align-self permet à un enfant de se positionner différemment des autres sur l'axe secondaire.

.item:nth-child(2) {
  align-self: flex-end;
}

Ici, seul le deuxième élément se place à la fin de l'axe secondaire.

Les valeurs sont les mêmes que pour align-items.

C'est pratique lorsqu'on veut casser ponctuellement l'alignement défini sur le parent.

flex-grow

flex-grow permet à un enfant de grandir pour occuper l'espace libre.

.item {
  flex-grow: 1;
}

Le navigateur calcule l'espace restant dans le conteneur, puis le distribue entre les enfants qui ont une valeur de flex-grow supérieure à 0.

Par défaut :

flex-grow: 0;

Si un seul élément a flex-grow: 1, il récupère tout l'espace restant.

Si plusieurs éléments ont flex-grow, l'espace est réparti selon leurs proportions :

.item1 {
  flex-grow: 1;
}

.item2 {
  flex-grow: 2;
}

Ici, le second élément recevra deux fois plus d'espace supplémentaire que le premier.

flex-shrink

flex-shrink fait l'inverse : il permet à un enfant de rétrécir si l'espace manque.

.item {
  flex-shrink: 1;
}

Par défaut, les éléments flex ont justement cette capacité de rétrécir pour tenir sur une ligne.

Si on ne veut pas qu'un élément rétrécisse :

.item {
  flex-shrink: 0;
}

Dans ce cas, ce sont les autres éléments qui devront encaisser la réduction.

Comme pour flex-grow, on peut jouer avec des ratios.

flex-basis

flex-basis permet de définir la taille de base d'un élément avant que l'espace libre ou manquant soit distribué.

.item {
  flex-basis: 100px;
}

On peut le voir comme une largeur de référence pour le calcul flex.

Dans beaucoup de cas, la largeur ou la hauteur de l'élément suffit déjà. Mais flex-basis devient utile quand on veut dissocier la taille de base du comportement final.

La propriété raccourcie flex

Les propriétés flex-grow, flex-shrink et flex-basis peuvent être regroupées :

flex: 1;
flex: 1 1 auto;
flex: 1 0 200px;

La lecture est la suivante :

  • première valeur : flex-grow
  • deuxième valeur : flex-shrink
  • troisième valeur : flex-basis

Cette forme raccourcie est très fréquente en pratique.

order

La propriété order permet de changer l'ordre visuel des éléments.

.item1 {
  order: 2;
}

.item2 {
  order: 1;
}

.item3 {
  order: 3;
}

Les éléments seront affichés selon la valeur numérique la plus petite vers la plus grande.

Par défaut :

order: 0;

On peut aussi utiliser des valeurs négatives pour faire remonter un élément avant les autres.

Point de vigilance sur order

order change seulement l'ordre visuel. L'ordre HTML, lui, ne change pas. Cela peut provoquer des comportements surprenants lors :

  • de la sélection de texte
  • de la navigation au clavier
  • de certaines interactions d'accessibilité

Il faudra donc être vigilant lors de l'utilisation de cette propriétée.

inline-flex

Comme pour block et inline, il existe une variante :

display: inline-flex;

Dans ce cas, le conteneur garde la logique flex, mais il se comporte lui-même comme un élément inline.

Cela signifie notamment qu'il prend par défaut la largeur de son contenu, au lieu d'occuper toute la largeur disponible.

Ce n'est pas le cas le plus fréquent, mais c'est parfois utile pour certains composants.

Exemple concret : un menu de navigation

Un bon cas d'usage des flexbox, c'est un menu.

Supposons une navigation qui contient plusieurs liens. Si on laisse le comportement normal des éléments inline, l'espacement dépend souvent des espaces présents dans le HTML, ce qui n'est pas idéal.

Avec flexbox, on peut reprendre la main sur l'alignement.

nav {
  display: flex;
  justify-content: space-evenly;
}

Cela permet de répartir les liens de manière uniforme.

Une autre approche consiste à faire grandir chaque lien :

nav {
  display: flex;
}

nav a {
  flex-grow: 1;
  text-align: center;
  padding: 10px;
}

Dans ce cas, chaque lien prend la même place disponible, ce qui facilite aussi la création d'un effet de survol sur toute la largeur de la zone.

Par exemple :

nav a:hover {
  background: rgba(255, 255, 255, 0.2);
}

Cette approche donne souvent un résultat plus propre qu'un simple alignement d'éléments inline.

Ce qu'il faut retenir

Les flexbox servent à organiser les enfants d'un conteneur le long d'un axe principal.

Les propriétés du parent permettent notamment de :

  • choisir la direction avec flex-direction
  • distribuer les éléments avec justify-content
  • les aligner sur l'axe secondaire avec align-items
  • autoriser le retour à la ligne avec flex-wrap
  • espacer les éléments avec gap

Les propriétés des enfants permettent de :

  • modifier ponctuellement l'alignement avec align-self
  • faire grandir un élément avec flex-grow
  • le faire rétrécir avec flex-shrink
  • définir une base de calcul avec flex-basis
  • changer son ordre visuel avec order

Au début, ces propriétés peuvent sembler un peu abstraites et on aura tendance à les mélanger assez souvent. Mais avec la pratique vous apprendrez les cas d'usages et vous verrez le rôle de chacune de ces propriétés, ce qui aidera grandement à les mémoriser.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager