Introduction au Développement HTML et CSS
Introduction au Développement HTML et CSS

Le système Flexbox : Alignement, Justification et Propriétés Flex

Introduction au Système Flexbox

Bienvenue dans cette leçon dédiée au système Flexbox, un module de mise en page CSS3 fondamental pour le développement web moderne. Dans le contexte de notre cours d'introduction au développement HTML et CSS, il est crucial de maîtriser Flexbox car il résout bon nombre de défis de mise en page qui étaient autrefois complexes et fastidieux à gérer avec des méthodes plus anciennes comme les float ou inline-block.

Qu'est-ce que Flexbox ? Flexbox, ou "Flexible Box Layout", est un modèle de disposition unidimensionnel. Cela signifie qu'il organise les éléments soit en ligne (sur un axe horizontal), soit en colonne (sur un axe vertical), mais pas sur les deux axes simultanément comme le ferait CSS Grid. Son objectif principal est de fournir un moyen plus efficace de disposer, d'aligner et de distribuer l'espace entre les éléments d'un conteneur, même lorsque la taille de ces éléments est inconnue ou dynamique.

Pourquoi utiliser Flexbox ? Avant Flexbox, centrer un élément verticalement ou distribuer l'espace de manière égale entre plusieurs éléments pouvait être un véritable casse-tête. Flexbox simplifie énormément ces tâches, rendant la création de mises en page responsives et adaptatives beaucoup plus intuitive et robuste.

Dans cette leçon, nous allons explorer en détail les concepts clés de Flexbox, en nous concentrant spécifiquement sur les propriétés d'alignement (justify-content, align-items, align-content) et les propriétés flex (flex-grow, flex-shrink, flex-basis) qui sont au cœur de sa puissance.

Les Fondamentaux du Flexbox : Conteneur et Éléments

Le système Flexbox repose sur deux concepts principaux :

  1. Le Conteneur Flex (Flex Container) : C'est l'élément parent qui va contenir les éléments à organiser. Pour transformer un élément en conteneur flex, vous devez lui appliquer la propriété display: flex; ou display: inline-flex;.

    • display: flex; : Le conteneur se comporte comme un élément de bloc, occupant toute la largeur disponible par défaut.
    • display: inline-flex; : Le conteneur se comporte comme un élément en ligne, n'occupant que l'espace nécessaire à son contenu.
  2. Les Éléments Flex (Flex Items) : Ce sont les enfants directs du conteneur flex. Une fois le parent défini comme conteneur flex, ses enfants directs deviennent automatiquement des éléments flex et peuvent être contrôlés par les propriétés Flexbox.

Un concept crucial à comprendre est celui des axes :

  • L'Axe Principal (Main Axis) : C'est l'axe le long duquel les éléments flex sont disposés. Sa direction est définie par la propriété flex-direction.
  • L'Axe Secondaire (Cross Axis) : C'est l'axe perpendiculaire à l'axe principal.

Par défaut, l'axe principal est horizontal (de gauche à droite) et l'axe secondaire est vertical (de haut en bas).

Propriétés du Conteneur Flex (Flex Container)

Les propriétés appliquées au conteneur flex déterminent comment ses enfants (les éléments flex) sont disposés et alignés.

1. flex-direction : Définir l'Axe Principal

Cette propriété établit l'axe principal, déterminant la direction dans laquelle les éléments flex seront placés.

  • row (par défaut) : Les éléments sont disposés en ligne, de gauche à droite (ou de droite à gauche pour les langues RTL). L'axe principal est horizontal.
  • row-reverse : Les éléments sont disposés en ligne, mais dans l'ordre inverse.
  • column : Les éléments sont disposés en colonne, de haut en bas. L'axe principal est vertical.
  • column-reverse : Les éléments sont disposés en colonne, mais dans l'ordre inverse.

2. flex-wrap : Gérer le Retour à la Ligne

Cette propriété contrôle si les éléments flex doivent passer à la ligne suivante si l'espace est insuffisant dans le conteneur.

  • nowrap (par défaut) : Tous les éléments flex restent sur une seule ligne, pouvant potentiellement déborder du conteneur.
  • wrap : Les éléments flex passent à la ligne suivante si nécessaire.
  • wrap-reverse : Les éléments flex passent à la ligne suivante, mais les lignes sont disposées dans l'ordre inverse.

3. flex-flow : Raccourci pour flex-direction et flex-wrap

C'est un raccourci pour combiner flex-direction et flex-wrap. Par exemple, flex-flow: row wrap; est équivalent à flex-direction: row; flex-wrap: wrap;.

4. justify-content : Alignement des Éléments sur l'Axe Principal

Cette propriété est l'une des plus utilisées pour distribuer l'espace et aligner les éléments le long de l'axe principal.

  • flex-start (par défaut) : Les éléments sont regroupés au début de l'axe principal.
  • flex-end : Les éléments sont regroupés à la fin de l'axe principal.
  • center : Les éléments sont centrés sur l'axe principal.
  • space-between : Le premier élément est au début et le dernier est à la fin ; l'espace restant est réparti également entre les éléments.
  • space-around : Les éléments sont répartis de manière égale avec un espace égal autour d'eux (l'espace autour des bords est la moitié de l'espace entre les éléments).
  • space-evenly : Les éléments sont répartis de manière égale avec un espace égal entre eux et autour des bords.

5. align-items : Alignement des Éléments sur l'Axe Secondaire

Cette propriété aligne les éléments flex le long de l'axe secondaire, perpendiculaire à l'axe principal. Elle s'applique à tous les éléments sur une seule ligne.

  • stretch (par défaut) : Les éléments s'étirent pour remplir la hauteur/largeur du conteneur (si aucune hauteur/largeur n'est définie pour eux).
  • flex-start : Les éléments sont regroupés au début de l'axe secondaire.
  • flex-end : Les éléments sont regroupés à la fin de l'axe secondaire.
  • center : Les éléments sont centrés sur l'axe secondaire.
  • baseline : Les éléments sont alignés sur leur ligne de base (particulièrement utile pour le texte).

6. align-content : Alignement des Lignes Multiples sur l'Axe Secondaire

Cette propriété est similaire à justify-content, mais elle s'applique à l'axe secondaire et uniquement lorsque le conteneur a plusieurs lignes (flex-wrap: wrap;). Elle gère la distribution de l'espace entre les lignes d'éléments.

  • stretch (par défaut) : Les lignes s'étirent pour occuper l'espace restant.
  • flex-start : Les lignes sont regroupées au début de l'axe secondaire.
  • flex-end : Les lignes sont regroupées à la fin de l'axe secondaire.
  • center : Les lignes sont centrées sur l'axe secondaire.
  • space-between : La première ligne est au début et la dernière à la fin ; l'espace restant est réparti également entre les lignes.
  • space-around : Les lignes sont réparties avec un espace égal autour d'elles.

Propriétés des Éléments Flex (Flex Items)

Les propriétés suivantes s'appliquent directement aux éléments flex, permettant de contrôler leur comportement individuel au sein du conteneur.

1. order : Modifier l'Ordre Visuel

Cette propriété permet de modifier l'ordre visuel des éléments flex, indépendamment de leur ordre dans le code HTML. La valeur par défaut est 0. Un nombre négatif placera l'élément plus tôt, un nombre positif plus tard.

2. flex-grow : Capacité à Grandir

Définit la capacité d'un élément flex à grandir et à occuper l'espace libre restant dans le conteneur. La valeur est un nombre (unité sans dimension).

  • flex-grow: 1; : L'élément prendra une part égale de l'espace libre disponible.
  • flex-grow: 2; : L'élément prendra deux fois plus d'espace libre que les éléments avec flex-grow: 1;.
  • flex-grow: 0; (par défaut) : L'élément ne grandit pas.

3. flex-shrink : Capacité à Rétrécir

Définit la capacité d'un élément flex à rétrécir si l'espace est insuffisant. La valeur est un nombre (unité sans dimension).

  • flex-shrink: 1; (par défaut) : L'élément peut rétrécir si nécessaire.
  • flex-shrink: 0; : L'élément ne rétrécira jamais, conservant sa taille initiale (sauf si flex-basis est plus grand que le conteneur et que l'élément n'a pas de max-width).

4. flex-basis : Taille Initiale d'un Élément

Définit la taille par défaut d'un élément flex avant que l'espace restant ne soit distribué. Elle peut être une longueur (ex: 100px, 50%) ou le mot-clé auto (par défaut), qui signifie que la taille est basée sur la taille du contenu de l'élément.

5. flex : Raccourci pour flex-grow, flex-shrink, et flex-basis

C'est un raccourci pour les trois propriétés précédentes. L'ordre est flex-grow, flex-shrink, flex-basis.

  • flex: 1; est un raccourci pour flex: 1 1 0%;. Signifie : grandit, rétrécit, et a une taille de base de 0.
  • flex: auto; est un raccourci pour flex: 1 1 auto;. Signifie : grandit, rétrécit, et a une taille de base automatique (basée sur le contenu ou width/height).
  • flex: none; est un raccourci pour flex: 0 0 auto;. Signifie : ne grandit pas, ne rétrécit pas, et a une taille de base automatique.

6. align-self : Alignement Individuel sur l'Axe Secondaire

Cette propriété permet d'aligner un seul élément flex individuellement le long de l'axe secondaire, ignorant la valeur align-items définie sur le conteneur. Ses valeurs sont les mêmes que align-items: auto (par défaut, hérite de align-items), flex-start, flex-end, center, baseline, stretch.

Exemples Pratiques

Mettons en pratique ces concepts avec quelques exemples concrets.

Exemple 1 : Centrage et Distribution Horizontale

Cet exemple montre comment centrer des éléments horizontalement et verticalement en utilisant justify-content et align-items.

HTML :

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemple Flexbox - Centrage</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="flex-container-1">
        <div class="flex-item">Item 1</div>
        <div class="flex-item">Item 2</div>
        <div class="flex-item">Item 3</div>
    </div>
</body>
</html>

CSS (styles.css) :

body {
    font-family: Arial, sans-serif;
    margin: 0;
    display: flex; /* Pour centrer le conteneur principal si besoin */
    min-height: 100vh; /* Permet au conteneur de prendre toute la hauteur de la vue */
    justify-content: center;
    align-items: center;
    background-color: #f0f0f0;
}

.flex-container-1 {
    display: flex; /* Déclare cet élément comme un conteneur flex */
    background-color: #007bff;
    padding: 20px;
    border-radius: 8px;
    width: 80%; /* Largeur pour le conteneur */
    min-height: 200px; /* Hauteur minimale pour voir l'effet de align-items */
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);

    /* Propriétés clés pour l'alignement et la justification */
    flex-direction: row; /* Les items sont disposés en ligne (par défaut) */
    justify-content: center; /* Centre les items horizontalement sur l'axe principal */
    align-items: center; /* Centre les items verticalement sur l'axe secondaire */
}

.flex-item {
    background-color: #ffffff;
    color: #333;
    padding: 25px 40px;
    margin: 10px;
    border-radius: 5px;
    font-size: 1.2em;
    font-weight: bold;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

Explication de l'exemple 1 :

  1. display: flex; sur .flex-container-1 transforme la div en conteneur flex.
  2. flex-direction: row; est la valeur par défaut, donc les items sont alignés horizontalement.
  3. justify-content: center; centre les .flex-item sur l'axe principal (horizontal ici). L'espace libre est réparti de manière égale de chaque côté du groupe d'items.
  4. align-items: center; centre les .flex-item sur l'axe secondaire (vertical ici). Cela est visible grâce au min-height de .flex-container-1.
  5. Le body est également un conteneur flex pour centrer flex-container-1 lui-même sur toute la page.

Exemple 2 : Flexibilité des Éléments et Retour à la Ligne

Cet exemple illustre comment les éléments flex peuvent grandir ou rétrécir (flex-grow, flex-shrink, flex-basis) et revenir à la ligne (flex-wrap).

HTML :

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemple Flexbox - Flexibilité</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="flex-container-2">
        <div class="flex-item-grow">Item Grow</div>
        <div class="flex-item-shrink">Item Shrink</div>
        <div class="flex-item-basis">Item Basis</div>
        <div class="flex-item-grow">Item Grow</div>
        <div class="flex-item-basis">Item Basis</div>
    </div>
</body>
</html>

CSS (styles.css) :

body {
    font-family: Arial, sans-serif;
    margin: 0;
    display: flex;
    flex-direction: column; /* Permet d'empiler les exemples si plusieurs */
    min-height: 100vh;
    justify-content: flex-start;
    align-items: center;
    background-color: #f0f0f0;
    padding: 20px;
}

.flex-container-2 {
    display: flex;
    background-color: #28a745; /* Vert pour la distinction */
    padding: 20px;
    border-radius: 8px;
    width: 90%;
    margin-top: 40px; /* Séparation des exemples */
    min-height: 250px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);

    flex-direction: row;
    flex-wrap: wrap; /* Permet aux items de passer à la ligne */
    justify-content: space-around; /* Distribue l'espace autour des items */
    align-items: flex-start; /* Aligne les items en haut des lignes */
    align-content: space-between; /* Distribue l'espace entre les lignes (si plusieurs) */
}

.flex-item-grow,
.flex-item-shrink,
.flex-item-basis {
    background-color: #ffffff;
    color: #333;
    padding: 25px 40px;
    margin: 10px;
    border-radius: 5px;
    font-size: 1.1em;
    font-weight: bold;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    min-width: 150px; /* Une largeur de base pour les items */
    height: 100px; /* Une hauteur fixe pour mieux visualiser wrap */
}

.flex-item-grow {
    flex: 1; /* Raccourci pour flex-grow: 1, flex-shrink: 1, flex-basis: 0% */
    /* Cela signifie qu'il grandira pour prendre l'espace disponible */
    background-color: #ffc107; /* Jaune */
}

.flex-item-shrink {
    flex-shrink: 0; /* Ne rétrécira jamais, conserve sa taille de base */
    flex-basis: 200px; /* Taille initiale plus grande */
    background-color: #dc3545; /* Rouge */
}

.flex-item-basis {
    flex-basis: 300px; /* Définit une taille initiale spécifique */
    flex-grow: 0; /* Ne grandit pas */
    flex-shrink: 1; /* Peut rétrécir si nécessaire */
    background-color: #17a2b8; /* Bleu clair */
}

Explication de l'exemple 2 :

  1. flex-wrap: wrap; sur .flex-container-2 est essentiel. Il permet aux éléments de passer à la ligne suivante lorsque la largeur du conteneur est insuffisante.
  2. justify-content: space-around; et align-content: space-between; (pour les lignes) gèrent la distribution de l'espace sur les axes.
  3. .flex-item-grow : flex: 1; est un raccourci très courant. Il signifie que cet élément peut grandir pour remplir l'espace disponible (si les autres ne le prennent pas). Il se comportera aussi comme s'il avait flex-basis: 0%;, ce qui le rend très flexible.
  4. .flex-item-shrink : flex-shrink: 0; l'empêche de rétrécir. Si le conteneur est trop petit, cet item gardera sa flex-basis: 200px; et pourra provoquer un débordement.
  5. .flex-item-basis : flex-basis: 300px; lui donne une taille initiale de 300px. flex-grow: 0; l'empêche de grandir au-delà de cette taille (sauf si forcé par le contenu). flex-shrink: 1; lui permet de rétrécir si nécessaire, mais en partant de 300px.

En redimensionnant la fenêtre du navigateur, vous verrez comment les éléments interagissent :

  • Les "Item Grow" essaieront de prendre tout l'espace libre restant.
  • "Item Shrink" résistera au rétrécissement.
  • "Item Basis" tentera de maintenir sa taille de 300px et ne grandira pas, mais rétrécira si la place manque.
  • Les items passeront à la ligne quand il n'y aura plus assez d'espace horizontal, grâce à flex-wrap: wrap.

Conclusion

Le système Flexbox est un outil incroyablement puissant et flexible pour la création de mises en page unidimensionnelles en CSS. La maîtrise des propriétés du conteneur (notamment display, flex-direction, flex-wrap, justify-content, align-items, et align-content) et des propriétés des items (order, flex-grow, flex-shrink, flex-basis, flex, align-self) est essentielle pour tout développeur web moderne.

Grâce à Flexbox, des tâches complexes comme le centrage parfait d'éléments, la distribution équitable de l'espace ou la réorganisation visuelle des contenus deviennent des jeux d'enfants. Rappelez-vous que Flexbox est idéal pour la disposition le long d'un seul axe. Pour des mises en page plus complexes et bidimensionnelles, vous devrez vous tourner vers son cousin, CSS Grid, que nous aborderons dans une leçon future.

N'hésitez pas à expérimenter avec les valeurs des différentes propriétés dans vos propres projets. La meilleure façon de comprendre Flexbox est de le pratiquer !