Flexbox

Flexbox range des éléments sur une ligne, ou sur une colonne, et répartit l’espace entre eux. Trois propriétés suffisent à couvrir la moitié des mises en page d’un site.

Qu’est-ce que Flexbox ?

Avant Flexbox, centrer un élément verticalement demandait un calcul et deux propriétés de positionnement. Depuis, cela demande deux déclarations.

Avant Flexbox

Centrage vertical

css

position: absolute;
top: 50%;
transform: translateY(-50%);

Complexe et fragile

Colonnes égales

css

float: left;
width: 33.333%;
/* + clearfix hack */

Calculs et bricolages

Avec Flexbox

Centrage parfait

css

display: flex;
justify-content: center;
align-items: center;

Simple et lisible

Colonnes flexibles

css

display: flex;
gap: 1rem;
/* Items: flex: 1 */

Équilibrées d’elles-mêmes

Les quatre mots à connaître

Flex container
L’élément parent, celui qui porte display: flex.
Flex items
Ses enfants directs, et eux seuls.
Main axis
L’axe principal, horizontal par défaut. C’est lui que justify-content gouverne.
Cross axis
L’axe perpendiculaire au précédent. C’est lui que align-items gouverne.
L’axe principal court de gauche à droite, l’axe transversal de haut en bas. Changer flex-direction les échange.

Les propriétés du conteneur

Quatre propriétés se posent sur le conteneur, et gouvernent tous ses enfants d’un coup.

display: flex

Une seule déclaration transforme un élément en conteneur flex. Ses enfants directs se rangent alors sur une ligne, au lieu de s’empiler.

css

/* Activation de Flexbox */
.container {
    display: flex;
}

/* Alternative inline */
.container-inline {
    display: inline-flex;
}

inline-flex fait la même chose, mais le conteneur lui-même reste dans le fil du texte.
Sans flex, chaque bloc occupe toute la largeur. Avec flex, les trois se partagent la ligne.

Explorer justify-content

justify-content

1
2
3

justify-content: ;

justify-content répartit les éléments le long de l’axe principal — horizontalement, tant que flex-direction vaut row.

Explorer align-items

align-items

1
Plus grand
3

align-items: ;

align-items gouverne l’axe transversal. La valeur stretch, par défaut, étire les éléments sur toute la hauteur du conteneur.

Explorer flex-direction

flex-direction

1
2
3

flex-direction: ;

flex-direction échange les deux axes. En column, c’est justify-content qui gouverne la verticale, et align-items l’horizontale.

gap : l’espacement, sans marges

gap définit l’espace entre les éléments, et seulement entre eux. Aucun espace ne traîne au début ni à la fin.

Les trois écritures

css

gap: 1rem;          /* Même espacement partout */
gap: 1rem 2rem;    /* row-gap column-gap */

row-gap: 1rem;
column-gap: 2rem;

gap est la forme raccourcie de row-gap et column-gap.

Ce que gap apporte face aux marges

  • Plus simple à écrire qu’une marge posée sur chaque enfant
  • Aucun espace superflu au début ni à la fin de la ligne
  • Fonctionne avec flex-wrap, y compris entre les lignes
  • Identique en Flexbox et en Grid
La marge posée sur chaque élément en laisse une de trop à droite. gap n’espace qu’entre les éléments.

Explorer la valeur de gap

gap

1
2
3
4
5

gap: ;

Les libellés donnent l’équivalent en pixels ; la déclaration, elle, s’écrit en rem — une unité qui suit la taille de texte choisie par le lecteur.

Explorer flex-direction avec un gap fixe

flex-direction

1
2
3

flex-direction: ;

Le même gap sépare les colonnes en row, et les lignes en column. Une seule déclaration couvre les deux cas.

Quelle unité choisir

Unités absolues

css

gap: 10px;   /* Pixels */
gap: 1cm;    /* Centimètres */
gap: 12pt;   /* Points */
  • Valeur fixe, quel que soit l’écran
  • Aucune adaptation
  • Contrôle précis

Unités relatives

css

gap: 1rem;   /* Root em */
gap: 2em;    /* Element em */
gap: 5%;     /* Pourcentage */
  • Suit la taille de texte du lecteur
  • Adaptatif sans effort
  • Cohérent avec le reste de la page

Unités de fenêtre

css

gap: 2vw;    /* Viewport width */
gap: 1vh;    /* Viewport height */
gap: 1vmin;  /* Plus petit des deux */
  • Relatif à la taille de l’écran
  • Très adaptatif
  • Mise en page fluide

En pratique

rem est le choix par défaut : il suit la taille de texte choisie par le lecteur, ce que px ignore. Réservez px aux traits fins — une bordure, un séparateur — et les unités de fenêtre aux espacements qui doivent respirer avec l’écran.

Deux espacements différents : row-gap et column-gap

css

/* Espacement différencié */
.container {
    display: flex;
    flex-wrap: wrap;
    row-gap: 2rem;      /* Vertical */
    column-gap: 1rem;   /* Horizontal */
}

/* Équivalent raccourci */
gap: 2rem 1rem;         /* row column */

La forme raccourcie prend la valeur des lignes en premier.

Quand cela sert

  • Grilles construites avec flex-wrap
  • Cartes qui se réorganisent selon la largeur
  • Formulaires sur plusieurs colonnes
  • Galeries d’images
gap: 1rem 0.5rem — 1rem entre les lignes, 0.5rem entre les colonnes.

Deux usages courants de gap

Les deux cas où gap remplace le plus souvent une série de marges.

Barre d’outils

css

.toolbar {
    display: flex;
    gap: 0.5rem;
    padding: 0.75rem;
    background: #f8f9fa;
}
Quatre boutons régulièrement espacés, sans marge sur aucun d’eux.

Tags et badges

css

.tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
flex-wrap fait passer les tags à la ligne ; gap espace aussi les lignes entre elles.

Trois mises en page courantes

Les mêmes trois propriétés, appliquées à ce qu’on rencontre sur presque tous les sites.

Le centrage parfait

Centrer horizontalement et verticalement a longtemps été le problème le plus cité du CSS. Trois déclarations le règlent.

css

/* Le Saint Graal du CSS */
.center-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

  • Fonctionne quel que soit le contenu
  • Adaptatif sans réglage
  • Trois lignes de CSS
Le bloc est au centre, sur les deux axes, quelle que soit la taille du conteneur.

La barre de navigation

Une marque à gauche, un menu à droite, le tout aligné verticalement : c’est space-between plus align-items.

css

/* Navigation principale */
.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 2rem;
}

.nav-menu {
    display: flex;
    gap: 2rem;
}

  • La marque reste à gauche, le menu à droite
  • Aucun flottant, aucun calcul de largeur
  • Le menu s’espace tout seul
space-between pousse le premier élément à gauche et le dernier à droite.

La grille de cartes

flex-wrap autorise le retour à la ligne, et la notation flex: 1 1 300px donne à chaque carte une largeur de départ qu’elle peut dépasser ou réduire.

css

/* Container des cards */
.cards-container {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

/* Cards individuelles */
.card {
    flex: 1 1 300px;
    background: white;
    border-radius: 8px;
    padding: 1rem;
}

  • 300 px de largeur de départ par carte
  • S’élargissent pour remplir la ligne
  • Passent à la ligne d’elles-mêmes
Réduisez la largeur du cadre : les cartes se réorganisent sans média query.

Exercice pratique

  1. Exercice : un tableau de bord d’administration

    Un en-tête horizontal, une colonne fixe de 250 px, une zone principale qui prend le reste.

    Ce que vous devez obtenir

    • Un en-tête avec une navigation horizontale
    • Une barre latérale de 250 px, de largeur fixe
    • Une zone principale qui occupe l’espace restant
    • Des widgets en grille, qui passent à la ligne
    • Tout l’alignement obtenu par Flexbox, sans positionnement absolu

    Les propriétés à employer

    • display: flex — sur le body, l’en-tête, la mise en page et la grille
    • flex-direction: column — pour empiler en-tête et corps
    • justify-content: space-between — pour l’en-tête
    • flex: 1 — pour que la zone principale prenne le reste
    • flex-wrap: wrap et gap — pour la grille de widgets

    À relire dans le cours

    • La section « Les propriétés du conteneur » pour justify-content et flex-direction.
    • La section « gap » pour l’espacement de la grille.
    • L’exemple « La grille de cartes » pour la notation flex: 1 1 300px.

    html

    <!DOCTYPE html>
    <html lang="fr">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Dashboard Admin - Exercice Flexbox</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
    
            body {
                font-family: Arial, sans-serif;
                /* TODO: Ajouter display: flex et flex-direction */
            }
    
            .header {
                background: #217cba;
                color: white;
                padding: 1rem;
                /* TODO: Faire une navigation horizontale avec flexbox */
            }
    
            .main-layout {
                /* TODO: Container flex horizontal pour sidebar + contenu */
            }
    
            .sidebar {
                background: #9b59b6;
                color: white;
                width: 250px;
                padding: 1rem;
                /* TODO: Faire un menu vertical avec flexbox */
            }
    
            .content {
                flex: 1;
                padding: 1rem;
            }
    
            .widgets {
                /* TODO: Grille de widgets responsive avec flexbox */
            }
    
            .widget {
                background: #ecf0f1;
                padding: 1rem;
                border-radius: 8px;
                min-height: 150px;
                /* TODO: Centrer le contenu */
            }
        </style>
    </head>
    <body>
        <header class="header">
            <div class="logo">Dashboard</div>
            <nav>
                <a href="#">Accueil</a>
                <a href="#">Utilisateurs</a>
                <a href="#">Paramètres</a>
            </nav>
        </header>
    
        <div class="main-layout">
            <aside class="sidebar">Menu</aside>
            <main class="content">
                <div class="widgets">
                    <div class="widget">Widget 1</div>
                    <div class="widget">Widget 2</div>
                    <div class="widget">Widget 3</div>
                </div>
            </main>
        </div>
    </body>
    </html>

    Recopiez ce fichier dans dashboard.html, puis remplacez chaque TODO par les déclarations manquantes.

    Les commentaires TODO du fichier de départ

    Chaque TODO marque une déclaration à écrire. Il y en a six : traitez-les de haut en bas, en rechargeant la page à chaque fois.

Les autres pages du parcours CSS

Flexbox est acquis

Vous savez ranger des éléments sur une ligne ou une colonne, les aligner et les espacer. La suite du parcours ajoute la deuxième dimension avec CSS Grid.