Apprendre CSS : Flexbox

Le module « Flexbox » regroupe un ensemble de propriétés CSS permettant de disposer ses éléments de manière flexible selon un axe principal.

Icône de calendrier
Débutant
9 chapitres

Module Flex

« Flexbox » est un module CSS dont le rôle est de faciliter le placement des éléments sur une page web. On parle de module car il s’agit d’un ensemble de propriétés CSS fonctionnant les unes avec les autres.

Le concept général de Flexbox (généralement abrégé « flex ») consiste à disposer des éléments selon un axe principal (ligne ou colonne). Cette méthode de placement est, comme son nom l’indique, flexible. Avec flex, les éléments vont pouvoir s’étirer ou se rétracter pour occuper l’espace disponible.

Créer une boîte flexible

Déclarer un conteneur

Pour déclarer que l’on va disposer des éléments dans un conteneur flexible, on applique la propriété display: flex sur une balise.

Cet élément deviendra ainsi le « flex-container » et ses enfants directs des « flex-items ».

copié !
<div class="flex">
	<div class="flex-item">...</div>
	<div class="flex-item">...</div>
	<div class="flex-item">...</div>
</div>
copié !
.flex {
	display: flex;
}

Un conteneur flexible se comporte comme un « block », il est néanmoins possible de la transformer en élément « inline » avec display: inline-flex.

Définir une direction

Par défaut, les éléments contenus dans un conteneur flexible seront disposés en ligne : c’est la direction de l’axe principal. Il est néanmoins possible de redéfinir cette direction avec la propriété flex-direction. 4 valeurs sont alors possibles :

  • row (défaut) : les éléments sont alignés en ligne, dans le sens de lecture de la langue (en français : de gauche à droite).
  • row-reverse : les éléments sont alignés en ligne, dans le sens inverse de lecture de la langue (en français : de droite à gauche).
  • column : les éléments sont alignés en colonne, de haut en bas.
  • column-reverse : les éléments sont alignés en colonne, de bas en haut.
copié !
.flex-container {
	display: flex;
	flex-direction: column;
}

Dans l’exemple ci-dessus, les éléments sont empilés.

Enveloppement

Les éléments flexibles vont s’accumuler les uns à la suite des autres sur l’axe principal (row ou column).

Si malgré s’être rétrécis au maximum les éléments flexibles venaient à ne plus être en mesure de rentrer dans le conteneur (width ou height insuffisante), alors ils déborderont.

On spécifie avec la propriété flex-wrap si les éléments doivent rester sur une seule ligne ou pas.

  • nowrap (défaut) : les éléments s’accumulent sans retour à la ligne (débordement).
  • wrap : les éléments s’accumulent avec retour à la ligne (vers le bas).
  • wrap-reverse : les éléments s’accumulent avec retour à la ligne (vers le haut).
copié !
.flex-container {
	display: flex;
	flex-wrap: wrap;
}

Espacements

Les propriétés column-gap et row-gap permettent respectivement de définir des espacements entre les colonnes et les lignes de nos éléments.

gap est une propriété abrégée permettant de les combiner.

copié !
.grid {
	display: flex;
	/* Equivalent à column-gap: 20px et row-gap: 20px */
	gap: 20px;
}

Alignement

Au sein d’un conteneur flexible, il va être possible de modifier l’alignement des éléments selon un axe spécifique.

L’alignement d’un élément est défini selon 2 axes :

  • L’axe principal (« main axis »)
  • L’axe croisé (« cross axis »)

Alignement sur l’axe principal

L’axe principal correspond à l’axe selon lequel se placent les éléments. Il s’agit par défaut de l’axe en ligne (flex-direction: row).

Pour aligner des éléments selon l’axe principal, on utilisera les propriétés commençant par justify-. À la différence des grilles, Flexbox traite notre contenu en tant que groupe et non individuellement dans chaque cellule. La quantité d’espace nécessaire pour disposer les éléments est calculée, et l’espace restant est alors distribué au travers de la propriété justify-content.

justify-content

Alignement du contenu du conteneur flexible.

La propriété justify-content permet d’aligner tous les éléments flexibles selon l’axe principal. Cette propriété prend généralement les valeurs suivantes :

copié !
.flex {
	justify-content: flex-start; /* Défaut */
	justify-content: center;
	justify-content: flex-end;
	justify-content: space-between;
	justify-content: space-around;
	justify-content: space-evenly;
}
  • flex-start (défaut) : les éléments flexibles sont alignés au début, selon l’axe principal.
  • center : les éléments flexibles sont alignés au centre, selon l’axe principal.
  • flex-end : les éléments flexibles sont alignés à la fin, selon l’axe principal.
  • space-between : les éléments flexibles sont espacés équitablement, selon l’axe principal.
  • space-around : les éléments flexibles sont espacés équitablement, selon l’axe principal. Un espace mesurant la moitié de l’espace séparant deux éléments est créé avant le premier élément et après le dernier élément.
  • space-evenly : les éléments flexibles sont espacés équitablement, selon l’axe principal. Un espace identique est aussi créé avant le premier élément et après le dernier élément.

Alignement sur l’axe transversal

L’axe transversal correspond à l’axe perpendiculaire à l’axe principal.

  • Si flex-direction est définie à row, alors il s’agit de column
  • Si flex-direction est définie à column, alors il s’agit de row

Pour aligner des éléments selon l’axe transversal, on utilisera les propriétés commençant par align-.

Sur l’axe transversal, align-self et align-items sont exploitables car nous avons potentiellement un espace supplémentaire dans le conteneur flexible.

align-self

Alignement individuel depuis un élément.

La propriété align-self permet d’aligner un élément selon l’axe transversal. Cette propriété prend généralement les valeurs suivantes :

copié !
.flex-item {
	align-self: stretch; /* Défaut */
	align-self: flex-start;
	align-self: center;
	align-self: flex-end;
}
  • stretch (défaut) : l’élément est étiré au maximum de la taille de l’axe transversal.
  • center : l’élément est aligné au centre de l’axe transversal.
  • flex-start : l’élément est aligné au début de l’axe transversal.
  • flex-end : l’élément est aligné à la fin de l’axe transversal.

align-items

Alignement individuel depuis le conteneur.

Pour aligner l’ensemble des éléments dans leurs cellules respectives selon l’axe de bloc, on utilisera plutôt align-items sur le conteneur de la boîte flexible.

Concrètement, appliquer justify-items sur le conteneur revient à appliquer justify-self sur chacun des éléments. Cette propriété possède les mêmes valeurs que align-self.

copié !
.flex {
	align-items: stretch; /* Défaut */
	align-items: flex-start;
	align-items: center;
	align-items: flex-end ;
}

align-content

Alignement du contenu de la boîte flexible.

La propriété align-content permet d’aligner tous les éléments flexibles selon l’axe principal. Cette propriété prend généralement les valeurs suivantes :

copié !
.flex {
	align-content: flex-start; /* Défaut */
	align-content: center;
	align-content: flex-end;
	align-content: space-between;
	align-content: space-around;
	align-content: space-evenly;
}
  • flex-start (défaut) : les éléments sont alignés au début de l’axe transversal.
  • center : les éléments sont alignés au centre de l’axe transversal.
  • flex-end : les éléments sont alignés à la fin de l’axe transversal.
  • space-between : les éléments sont espacés équitablement au sein de l’axe transversal.
  • space-around : les éléments sont espacés équitablement au sein de l’axe transversal. Un espace mesurant la moitié de l’espace séparant deux éléments est créé avant le premier élément et après le dernier élément.
  • space-evenly : les éléments sont espacés équitablement au sein de l’axe transversal. Un espace identique est aussi créé avant le premier élément et après le dernier élément.

Ordonner les éléments

Par défaut, les éléments flexibles sont disposés les uns à la suite des autres. Il est néanmoins possible de spécifier un ordre différent de celui du document avec la propriété order.

Par défaut tous les éléments ont la valeur order: 0. Les éléments sont appliqués dans l’ordre croissant des valeurs.

copié !
<div class="flex">
	<div class="flex-item" id="item-1">Item 1</div>
	<div class="flex-item" id="item-2">Item 2</div>
	<div class="flex-item" id="item-3">Item 3</div>
	<div class="flex-item" id="item-4">Item 4</div>
</div>
copié !
.flex{
	display: flex;
}

#item-1 {
	order: 1;
}

#item-3 {
	order: 15;
}

Les éléments s’afficheront dans l’ordre suivant : Item 2, Item 4, Item 1 et Item 3.

Dimension des éléments

Taille initiale

Par défaut, la place occupée par un élément flexible est équivalente à la dimension maximale (max-content) de son contenu. Si le contenu de ces boîtes est trop grand, alors la taille de l’élément est automatiquement réduite de manière à éviter un débordement du conteneur (overflow). Cette réduction peut aller jusqu’à atteindre la dimension minimale (min-width) possible de son contenu.

Pour définir manuellement la taille d’un élément flexible, on fera appel à la propriété flex-basis. La valeur par défaut est auto.

  • Si l’axe principal est défini à row, alors flex-basis définira la width
  • Si l’axe principal est défini à column, alors flex-basis définira la height
copié !
<div class="flex">
	<div class="flex-item">Item 1</div>
	<div class="flex-item">Item 2</div>
	<div class="flex-item">Item 3</div>
	<div class="flex-item">Item 4</div>
</div>
copié !
.flex {
	display: flex;
	flex-wrap: wrap;
	flex-direction: column;
	gap: 1rem;
	height: 300px;
}

.flex-item {
	flex-basis: 100px;
}

Facteur d’étirement

La propriété flex-grow définit le facteur d’expansion d’un élément flexible selon sa dimension principale.

Elle indique la quantité d’espace restant que l’élément devrait consommer dans un conteneur flexible relativement à la taille des autres éléments du même conteneur. Par défaut tous les éléments ont la valeur flex-grow: 0 (les éléments ne croissent donc pas automatiquement).

copié !
<div class="flex">
	<div class="flex-item" id="item-1">Item 1</div>
	<div class="flex-item" id="item-2">Item 2</div>
	<div class="flex-item" id="item-3">Item 3</div>
	<div class="flex-item" id="item-4">Item 4</div>
</div>
copié !
.flex {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
}

#item-2 {
	flex-grow: 1;
}

#item-3 {
	flex-grow: 2;
}
  • L’élément Item 2 grandira de 1/3 de l’espace restant (1 / 1 + 2)
  • L’élément Item 3 grandira de 2/3 de l’espace restant (2 / 1 + 2)
  • Les autres éléments ne grandissent pas

Facteur de rétrécissement

La propriété flex-shrink définit le facteur de rétrécissement d’un élément flexible.

Si la taille de l’ensemble des éléments flexibles est supérieure à la taille du conteneur, les éléments seront comprimés selon ce facteur. Par défaut tous les items ont la valeur flex-shrink: 1 (les éléments rétrécissent donc automatiquement).

copié !
<div class="flex">
	<div class="flex-item" id="item-1">Item 1</div>
	<div class="flex-item" id="item-2">Item 2</div>
	<div class="flex-item" id="item-3">Item 3</div>
	<div class="flex-item" id="item-4">Item 4</div>
</div>
copié !
.flex {
	display: flex;
	gap: 1rem;
}

#item-2 {
	flex-shrink: 0;
}

#item-3 {
	flex-shrink: 3;
}
  • L’élément Item 2 ne rétrécira pas
  • L’élément Item 3 va essayer de rétrécir 3 fois plus que les autres
  • Les autres éléments rétrécissent suffisamment pour ne pas dépasser du conteneur

Propriété raccourcie

La propriété flex est un condensé des propriétés flex-grow, flex-shrink et flex-basis. Elle est à définir sur un élément flexible.

flex: 1 1 200px signifie qu’un élément :

  • S’étire avec un facteur de 1
  • Rétrécit avec un facteur de 1
  • A une taille initiale de 200px

Responsive avec flex

Le potentiel de Flexbox est idéal pour mettre en place un design responsive. Cela se fait essentiellement en :

  • Modifiant la direction des éléments avec flex-direction (column sur mobile et row sur plus grande résolution)
  • Définissant des tailles initiales à nos éléments avec flex-basis
  • Rendant possible l’étirement de nos éléments avec flex-grow