Aller au contenu

9. Flexbox

"Flexbox" est un module qui permet d'organiser la mise en page manière flexible et adapté pour faire un site compatible avec plusieurs interfaces comme les smartphone et les tablettes? On parle de "module" car il s’agit d’un ensemble de propriétés CSS fonctionnant les unes avec les autres.


Flexbox c'est quoi ?

Flexbox pour "Flex box layout" et nous permet de faire des layouts plus facilement et plus rapidement en CSS. C'est le mode de layout qui est le plus utilisé et apprécié des développeurs web.

On va découvrir Flexbox dans les détails et on va surtout voir les méthodes "avancées" qui sont rarement vues comme flex-grow ou flex-shrink.

Origine de Flexbox

Avant le flexbox, la seule méthode d'ajouter des layout à nos éléments c'était le Flow Layout qui consiste à deux types d'éléments :

  • les éléments en flow
  • les éléments inline et block

Mais depuis 2013, flexbox a été introduit et il est tellement pratique qu'il a rapidement séduit les développeurs web.

Comment utiliser Flexbox ?

Il s'utilise avec une propriété display et une valeur flex :

HTML
<div class="flex-container">
    <div class="flex-item">...</div>
    <div class="flex-item">...</div>
    <div class="flex-item">...</div>
</div>
CSS
.flex-container {
  display: flex;
}

Une fois fait, le parent et tous les enfants vont changer de mode de layout pour être flexbox.

Ce mode de positionnement va avoir comme effet de les aligner, par défaut sur l'axe horizontal.

Il y a ensuite 3 propriétés qu'on va pouvoir appliquer sur le parent :

  • flex-direction : qui définit quel va être l'axe principal de ce layout
  • align-items: qui définit quel va être l'alignement sur l'axe secondaire
  • justify-content: qui définit quel va être l'alignement sur l'axe principal

Prenez le temps avec ce playground pour mieux comprend comment flexbox fonctionne :

Le plus compliqué à comprendre c'est la notion "d'axe".

C'est quoi les axes ?

flex-direction vient définir quel va être l'axe principal et par la suite, les propriétés comme align-items ou justify-content vont être appliquées sur cet axe :

Flex axes

align-items va aligner les éléments sur l'axe principal et justify-content va aligner les éléments sur l'axe secondaire.

Si tu veux, pour comprendre le concept de ces axes tu peux t'imaginer que l'axe principal va venir "piquer les éléments" tous entre eux, comme une brochette.

Flex axe primaire

Alors que l'axe secondaire va venir piquer les éléments mais tous individuellement :

Flex axe secondaire

Tu vois que les deux axes sont fondamentalement différents.

Car le premier, l'axe principal est défini uniquement par le container, car chaque élément est "sur la même brochette" et dépend des autres.

Quand avec l'axe secondaire, tout le monde peut être placé comme il veut.

Définir une direction

flex-direction qui définit quel va être l'axe principal de ce layout.

flex-direction: row

row permet de positionner les éléments flexibles horizontalement dans la même direction que le texte.

CSS
.flex-container {
    display: flex;
    flex-direction: row;
}

Voici le résultat en utilisent flex-direction: row :

01
02
03

flex-direction: row-reverse

row-reverse permet de positionner les éléments flexibles horizontalement dans la direction opposée et cela inversera l'ordre des éléments.

CSS
.flex-container {
    display: flex;
    flex-direction: row-reverse;
}

Voici le résultat en utilisent flex-direction: row-reverse :

01
02
03

flex-direction: column

Utiliser column pour positionner les éléments flexibles verticalement :

CSS
.flex-container {
    display: flex;
    flex-direction: column;
}

Voici le résultat en utilisent flex-direction: column :

01
02
03

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).
CSS
.flex-container {
    display: flex;
    flex-wrap: wrap;
}

La propriété flex-flow est un raccourci qui permet de condenser les propriétés flex-direction et flex-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.

Notez

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

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

Pour espacer les éléments flexibles, utiliser gap est préférable que d’utiliser margin ou padding car ces deux dernières propriétés vont également placer des espacements à l’extérieur des éléments, provoquant souvent des défauts d’alignement.

Align-self

C'est pour ça qu'il existe align-self qu'il est possible d'appliquer sur un élément pour le déplacer sur l'axe secondaire.

Tu peux voir ici qu'il est possible de déplacer l'élément rouge :

La taille des éléments

Il y a un concept important à comprendre avec le flexbox quand on parle de width.

La width est ce qu'on appelle une "suggestion" quand on est dans un élément flex, car le flexbox layout est désigné pour être flexible.

C'est pour ça que si je montre l'exemple suivant, tu verras que malgré une width de 1000px, l'élément dans flex ne possède pas cette largeur :

Alors que l'élément du dessous : OUI ! Pourquoi ?

Car l'élément du dessous est en flow layout et donc il considère la width comme une règle et pas une suggestion.

En flex, le but est que tout soit... bah flexible 🤔 et donc il va prendre la place disponible, comme son container n'a pas 1000px de largeur, il ne prend que la place disponible.

Flex-grow

flex-grow va permettre de définir qui a la priorité quand il s'agit de prendre de la place.

Tu peux voir que l'élément rouge, avec flex-grow: 1 va automatiquement prendre toute la place disponible.

C'est le concept de flex-grow, il vient définir la place disponible. La valeur qu'on lui ajoute est ce qu'on appelle un ratio, on vient définir à quel point cet élément va prendre de la place par rapport aux autres, qui sont part défaut à flex-grow: 0.

On peut voir que le container rouge n'est pas deux fois plus grand que les autres, il prend juste tous l'espace disponible.

Mais alors comment faire pour que l'élément rouge soit vraiment 2x plus grand que les autres ?

Flex 'shorthand'

Le flex 'shorthand' c'est ce que tu vas finalement le plus utiliser :

CSS
.element {
  flex: 1;
}

Quand on ajoute flex: 1 on vient définir 3 valeurs :

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0

Et c'est le flex-basis qui va nous intéresser ici, il correspond à :

  • La largeur du contenu quand on utilise flex-direction: row
  • La hauteur du contenu quand on utilise flex-direction: column

En fait, il s'adapte en fonction de la direction du layout.

Quand on lui met 0 (flex-basis: 0), on vient dire que l'élément ne prend plus aucune place, ce qui fait qu'il y a la même quantité d'espace à partager.

Rel vs Abs flex

Tu peux le voir juste ici, quand on utilise flex:1 on peut voir que l'élément prend l'espace disponible proportionnellement avec les autres éléments si ceux-ci sont aussi avec flex: 1 :

Notez

Dans l'exemple ci-dessus, la box 3 et 4 ont une largeur width initiale définit x2 de la largeur de 1 et 2.

Points importants

flex prend 3 paramètres :

  • flex-grow comme valeur sans unité
  • flex-shrink comme valeur sans unité
  • flex-basis comme valeur en px

Par défaut, flex-grow va distribuer l'espace restant de manière égale.

flex: 1 vient définir flex-grow: 1, et flex-basis: 0px (flex-shrink reste inchangé et garde sa valeur par défaut de 1)

Comme flex-basis: 0px est similaire à width (en row), on vient réduire la taille hypothétique de chaque élément au minimum et donc ils vont prendre la même taille.

Guide Interactif

Rien de mieux qu'un guide interactif pour mieux comprendre le fonctionnement de Flexbox. Guide Interactif mettez la page en français!

Apprendre le positionnement en s’amusant

Voici des sites vous permettant d’expérimenter l'usage des Flexbox de manière interactive et ludique:

Editeurs Visuels Flexbox

Parfois le meilleur moyen de découvrir une propriété CSS reste encore de jouer avec. Voici quelques sites où vous pourrez vous éclater avec les fonctionnalités et tout casser.

Sur ce petit CodePen de Gabi vous pourrez tester les différentes valeurs des propriétés et voir les résultats.

Playground

Un autre outils créé par Bennett Feely pour tester les différentes propriétés et explorer les possibilités de ce module CSS.

Flexplorer

Ce site vous propose des astuces de mises en page possible et grandement facilitées grâce à Flexbox. (par Phil Walton)

Flexplorer

C’est bien sympa de faire des mises en page, mais qu’en est-il de composants plus complexes comme des onglets ou des cartes ? C’est ce que vous propose de construire Flexbox Patterns (par CJ Cenizal)

Flexplorer