Cours HTML et CSS · Module 4: Flexbox

Créer une grille avec Flexbox

9 min de lecture
Dans cette leçon10

Tu dois présenter des photos des trésors d'un tombeau : plusieurs par rangée sur un ordinateur, les unes sous les autres sur un téléphone. Les anciens Égyptiens étaient des maîtres de l'organisation de l'espace, des colonnes symétriques des temples jusqu'au découpage précis des champs cultivés le long du Nil. Créer une grille (grid) avec Flexbox est l'équivalent moderne de ce savoir-faire. Nous allons voir étape par étape comment construire une mise en page responsive avec des colonnes flexibles, dont les largeurs sont exprimées en pourcentages, à la manière de frameworks comme Bootstrap ou Tailwind CSS.

Une brève histoire des mises en page

Dans les années 1990, on construisait les mises en page avec des tableaux HTML, alors que <table> sert aux données. Dans les années 2000, float et clear, que tu connais depuis le module sur le CSS, régnaient en maîtres. Flexbox, dont la spécification a pris sa forme actuelle en 2012, a enfin permis d'aligner des éléments en rangée sans astuces, et en 2017, les navigateurs ont introduit CSS Grid, conçu spécialement pour les grilles à deux dimensions. La grille construite avec Flexbox est toujours bien vivante, par exemple dans Bootstrap depuis la version 4.

Deux propriétés sur lesquelles repose la grille

La grille repose sur deux propriétés du conteneur : display: flex place les éléments en rangée, et flex-wrap: wrap leur permet de passer à une nouvelle ligne. Le reste tient en quatre étapes, dans un ordre fixe : active display: flex, ajoute flex-wrap: wrap, définis la largeur des colonnes, par exemple flex-basis: 33%, et enfin ajoute gap pour les espacements.

Étape 1 : Crée la structure de base d'un document HTML

D'abord, crée un nouveau fichier HTML et ajoute la structure de base du document. Ajoute un élément <div> avec la classe .flex-grid et plusieurs éléments <div> avec la classe .col, qui représenteront les colonnes de la grille :

1<!DOCTYPE html>
2<html lang="fr">
3<head>
4  <meta charset="UTF-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6  <link rel="stylesheet" href="styles.css"> <!-- Lien vers le fichier CSS -->
7  <title>Créer une grille avec Flexbox</title>
8</head>
9<body>
10  <div class="flex-grid">
11    <div class="col col-6">Colonne 1</div>
12    <div class="col col-6">Colonne 2</div>
13  </div>
14  <div class="flex-grid">
15    <div class="col col-4">Colonne 1</div>
16    <div class="col col-4">Colonne 2</div>
17    <div class="col col-4">Colonne 3</div>
18  </div>
19  <div class="flex-grid">
20    <div class="col col-3">Colonne 1</div>
21    <div class="col col-3">Colonne 2</div>
22    <div class="col col-3">Colonne 3</div>
23    <div class="col col-3">Colonne 4</div>
24  </div>
25</body>
26</html>

Chaque rangée est un .flex-grid distinct. Les colonnes partagent la classe col et ont une classe numérotée, par exemple col-6, qui indique combien des douze parts de la largeur la colonne occupe. Dans chaque rangée, les nombres totalisent 12.

Étape 2 : Crée un fichier CSS

Ouvre ou crée un nouveau fichier CSS et enregistre-le sous le nom styles.css. C'est vers lui que pointe la balise <link> de l'étape 1.

Étape 3 : Mise en forme de base

Ajoute des styles de base pour les éléments .flex-grid et .col, afin qu'ils soient visibles sur la page. C'est ici que la grille reçoit ses deux propriétés clés :

1body {
2  font-family: Arial, sans-serif;
3  margin: 0;
4  padding: 0;
5  display: flex;
6  justify-content: center;
7  align-items: center;
8  flex-direction: column;
9  gap: 20px;
10  min-height: 100vh;
11  background-color: #f0f0f0;
12}
13
14.flex-grid {
15  display: flex;
16  flex-wrap: wrap;
17  width: 80%;
18  background-color: #fff;
19  border: 1px solid #ddd;
20  padding: 10px;
21  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
22  gap: 10px;
23}
24
25.col {
26  background-color: lightblue;
27  padding: 20px;
28  text-align: center;
29  border: 1px solid #ccc;
30}

body est un conteneur flex en colonne, qui place les rangées les unes sous les autres. Chaque .flex-grid a display: flex, flex-wrap: wrap et gap: 10px, et .col reçoit un fond, un padding et une bordure, pour qu'on puisse la voir.

Étape 4 : Crée les classes de colonnes avec des valeurs en pourcentage

Ajoute des styles pour les classes de .col-1 à .col-12, qui définiront la largeur des colonnes en pourcentages. La formule est simple : le nombre qui figure dans le nom de la classe, divisé par 12 :

1.col-1 {
2  flex-basis: 8.33333333%;
3  max-width: 8.33333333%;
4}
5
6.col-2 {
7  flex-basis: 16.66666667%;
8  max-width: 16.66666667%;
9}
10
11.col-3 {
12  flex-basis: 25%;
13  max-width: 25%;
14}
15
16.col-4 {
17  flex-basis: 33.33333333%;
18  max-width: 33.33333333%;
19}
20
21.col-5 {
22  flex-basis: 41.66666667%;
23  max-width: 41.66666667%;
24}
25
26.col-6 {
27  flex-basis: 50%;
28  max-width: 50%;
29}
30
31.col-7 {
32  flex-basis: 58.33333333%;
33  max-width: 58.33333333%;
34}
35
36.col-8 {
37  flex-basis: 66.66666667%;
38  max-width: 66.66666667%;
39}
40
41.col-9 {
42  flex-basis: 75%;
43  max-width: 75%;
44}
45
46.col-10 {
47  flex-basis: 83.33333333%;
48  max-width: 83.33333333%;
49}
50
51.col-11 {
52  flex-basis: 91.66666667%;
53  max-width: 91.66666667%;
54}
55
56.col-12 {
57  flex-basis: 100%;
58  max-width: 100%;
59}

flex-basis définit la largeur de départ d'une colonne, et max-width sert de garde-fou au cas où quelqu'un ajouterait flex-grow à une colonne. Le choix de douze parts est délibéré, car 12 est divisible par 2, 3, 4 et 6. Si tu ne veux pas calculer, garde une marge : trois colonnes avec flex-basis: 30% tiendront sur une rangée avec des espacements courants.

Étape 5 : Des colonnes responsives

Pour rendre la grille responsive, nous pouvons utiliser des media queries et modifier les propriétés Flexbox en fonction de la largeur de l'écran :

1@media (max-width: 768px) {
2  .flex-grid {
3    flex-direction: column;
4  }
5
6  .col {
7    flex: none;
8    width: 100%;
9  }
10}

Sur les écrans de 768 pixels ou moins, la rangée place ses colonnes les unes sous les autres, et flex: none et width: 100% doivent les étirer sur toute la largeur.

Le piège : padding, bordures et espacements

Quand tu ouvriras la page, une surprise t'attend : deux colonnes col-6 ne se placeront pas côte à côte. Par défaut, flex-basis et max-width ne mesurent que le contenu de la colonne, donc le padding et la bordure s'ajoutent aux 50%, et l'espacement vient encore s'y ajouter. Le total dépasse 100%, et la seconde colonne passe à la ligne. Sur un téléphone, en revanche, le max-width des classes de colonnes s'applique toujours. Trois modifications ajoutées à la fin de styles.css corrigent cela :

1*,
2*::before,
3*::after {
4  box-sizing: border-box;
5}
6
7.col-3 { flex-basis: calc(25% - 7.5px); max-width: calc(25% - 7.5px); }
8.col-4 { flex-basis: calc(33.333% - 6.667px); max-width: calc(33.333% - 6.667px); }
9.col-6 { flex-basis: calc(50% - 5px); max-width: calc(50% - 5px); }
10
11@media (max-width: 768px) {
12  .col {
13    max-width: 100%;
14  }
15}

box-sizing: border-box, que tu connais depuis la leçon sur le modèle de boîte, inclut le padding et la bordure dans la largeur. À chaque colonne, nous retirons sa part des espacements : par exemple, deux colonnes col-6 se partagent un espacement, donc chacune cède 5 pixels. Sur un téléphone, max-width: 100% lève la limite. Tu découvriras la formule de ce genre de calcul dans la leçon sur gap.

Résultat

Après avoir réalisé les étapes 1 à 5, tes fichiers devraient ressembler à ceci. Ajoute les corrections de la section précédente tout à la fin de la feuille de style, pour qu'elles remplacent les règles précédentes.

Fichier HTML (index.html)

Le fichier HTML reste inchangé, il contient toujours trois rangées de colonnes :

1<!DOCTYPE html>
2<html lang="fr">
3<head>
4  <meta charset="UTF-8">
5  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6  <link rel="stylesheet" href="styles.css"> <!-- Lien vers le fichier CSS -->
7  <title>Créer une grille avec Flexbox</title>
8</head>
9<body>
10  <div class="flex-grid">
11    <div class="col col-6">Colonne 1</div>
12    <div class="col col-6">Colonne 2</div>
13  </div>
14  <div class="flex-grid">
15    <div class="col col-4">Colonne 1</div>
16    <div class="col col-4">Colonne 2</div>
17    <div class="col col-4">Colonne 3</div>
18  </div>
19  <div class="flex-grid">
20    <div class="col col-3">Colonne 1</div>
21    <div class="col col-3">Colonne 2</div>
22    <div class="col col-3">Colonne 3</div>
23    <div class="col col-3">Colonne 4</div>
24  </div>
25</body>
26</html>

Fichier CSS (styles.css)

La feuille de style rassemble toutes les règles des étapes 3, 4 et 5 au même endroit, dans l'ordre dans lequel tu les as écrites :

1body {
2  font-family: Arial, sans-serif;
3  margin: 0;
4  padding: 0;
5  display: flex;
6  justify-content: center;
7  align-items: center;
8  flex-direction: column;
9  gap: 20px;
10  min-height: 100vh;
11  background-color: #f0f0f0;
12}
13
14.flex-grid {
15  display: flex;
16  flex-wrap: wrap;
17  width: 80%;
18  background-color: #fff;
19  border: 1px solid #ddd;
20  padding: 10px;
21  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
22  gap: 10px;
23}
24
25.col {
26  background-color: lightblue;
27  padding: 20px;
28  text-align: center;
29  border: 1px solid #ccc;
30}
31
32.col-1 {
33  flex-basis: 8.33333333%;
34  max-width: 8.33333333%;
35}
36
37.col-2 {
38  flex-basis: 16.66666667%;
39  max-width: 16.66666667%;
40}
41
42.col-3 {
43  flex-basis: 25%;
44  max-width: 25%;
45}
46
47.col-4 {
48  flex-basis: 33.33333333%;
49  max-width: 33.33333333%;
50}
51
52.col-5 {
53  flex-basis: 41.66666667%;
54  max-width: 41.66666667%;
55}
56
57.col-6 {
58  flex-basis: 50%;
59  max-width: 50%;
60}
61
62.col-7 {
63  flex-basis: 58.33333333%;
64  max-width: 58.33333333%;
65}
66
67.col-8 {
68  flex-basis: 66.66666667%;
69  max-width: 66.66666667%;
70}
71
72.col-9 {
73  flex-basis: 75%;
74  max-width: 75%;
75}
76
77.col-10 {
78  flex-basis: 83.33333333%;
79  max-width: 83.33333333%;
80}
81
82.col-11 {
83  flex-basis: 91.66666667%;
84  max-width: 91.66666667%;
85}
86
87.col-12 {
88  flex-basis: 100%;
89  max-width: 100%;
90}
91
92@media (max-width: 768px) {
93  .flex-grid {
94    flex-direction: column;
95  }
96
97  .col {
98    flex: none;
99    width: 100%;
100  }
101}

L'ordre des règles compte : la media query se trouve à la fin, donc sur un téléphone, elle remplace les réglages précédents des colonnes. Pour la même raison, les corrections se placent après elle. Mon conseil : quand une mise en page a besoin de rangées et de colonnes à la fois, utilise CSS Grid, et réserve la grille Flexbox aux rangées simples.

Tâche supplémentaire

  1. Ajoute d'autres colonnes et expérimente avec différentes valeurs de flex-basis et de max-width, pour voir comment la mise en page de la grille change.
  2. Teste tes compétences en créant des mises en page plus complexes avec différentes combinaisons de propriétés Flexbox.
  3. Ajoute différents styles à ta grille, par exemple en modifiant les couleurs, les tailles de police et d'autres propriétés des éléments, pour mieux comprendre le fonctionnement des différentes options de Flexbox.

Essaie la grille dans l'éditeur ci-dessous. Tu la verras sous un autre angle : les conteneurs ont flex-wrap: wrap et une hauteur fixe, donc les éléments se répartissent sur plusieurs lignes, et align-content décide comment ces lignes se répartissent verticalement.

Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Flexbox - Align Content</title>
7    <link rel="stylesheet" href="style.css">
8</head>
9<body>
10    <div class="container">
11        <h1>Align Content - Répartition des lignes</h1>
12        <p class="subtitle">Contrôle la répartition des LIGNES d'éléments dans un conteneur avec flex-wrap</p>
13
14        <section class="demo-section">
15            <h2>align-content: flex-start</h2>
16            <div class="flex-container align-start">
17                <div class="flex-item">1</div>
18                <div class="flex-item">2</div>
19                <div class="flex-item">3</div>
20                <div class="flex-item">4</div>
21                <div class="flex-item">5</div>
22                <div class="flex-item">6</div>
23            </div>
24            <p class="description">Les lignes sont regroupées au début du conteneur</p>
25        </section>
26
27        <section class="demo-section">
28            <h2>align-content: center</h2>
29            <div class="flex-container align-center">
30                <div class="flex-item">1</div>
31                <div class="flex-item">2</div>
32                <div class="flex-item">3</div>
33                <div class="flex-item">4</div>
34                <div class="flex-item">5</div>
35                <div class="flex-item">6</div>
36            </div>
37            <p class="description">Les lignes sont centrées dans le conteneur</p>
38        </section>
39
40        <section class="demo-section">
41            <h2>align-content: space-between</h2>
42            <div class="flex-container align-between">
43                <div class="flex-item">1</div>
44                <div class="flex-item">2</div>
45                <div class="flex-item">3</div>
46                <div class="flex-item">4</div>
47                <div class="flex-item">5</div>
48                <div class="flex-item">6</div>
49            </div>
50            <p class="description">Première ligne en haut, dernière en bas, espacement égal entre les deux</p>
51        </section>
52
53        <section class="demo-section">
54            <h2>align-content: space-around</h2>
55            <div class="flex-container align-around">
56                <div class="flex-item">1</div>
57                <div class="flex-item">2</div>
58                <div class="flex-item">3</div>
59                <div class="flex-item">4</div>
60                <div class="flex-item">5</div>
61                <div class="flex-item">6</div>
62            </div>
63            <p class="description">Espacement égal autour de chaque ligne</p>
64        </section>
65
66        <section class="demo-section practice">
67            <h2>Exercice : étagère à trésors égyptiens</h2>
68            <p class="practice-description">Disposer les trésors du pharaon sur les étagères</p>
69
70            <div class="shelf-container">
71                <div class="shelf">
72                    <div class="treasure">◆</div>
73                    <div class="treasure">◆</div>
74                    <div class="treasure">◆</div>
75                    <div class="treasure">◆</div>
76                    <div class="treasure">◆</div>
77                    <div class="treasure">◆</div>
78                    <div class="treasure">◆</div>
79                    <div class="treasure">◆</div>
80                </div>
81            </div>
82
83            <div class="controls">
84                <button onclick="changeAlign('flex-start')">Start</button>
85                <button onclick="changeAlign('center')">Center</button>
86                <button onclick="changeAlign('space-between')">Between</button>
87                <button onclick="changeAlign('space-around')">Around</button>
88            </div>
89        </section>
90    </div>
91
92    <script>
93        function changeAlign(value) {
94            document.querySelector('.shelf').style.alignContent = value;
95        }
96    </script>
97</body>
98</html>

Retiens : une grille Flexbox, c'est un champ au bord du Nil divisé en douze parts égales, où flex-wrap: wrap permet de commencer de nouvelles rangées, et où les pourcentages indiquent combien de terre reçoit chaque colonne.

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelles sont les deux propriétés essentielles pour créer une grille avec Flexbox ?

Tâches pratiques dans le jeu

  • Tri vertical

    Range les étapes pour créer une grille responsive avec Flexbox :

  • Éditeur de code

    Crée une grille de 3 colonnes avec 6 éléments en utilisant display: flex, flex-wrap: wrap et flex-basis: 30% sur les éléments enfants.

  • Clique dans l'ordre

    Compose la déclaration raccourcie flex (grow: 1, shrink: 0, basis: 200px) :

  • Tri vertical

    Range les méthodes de mise en page CSS dans l'ordre chronologique :

Articles utiles