Cours HTML et CSS · Module 8: CSS Grid

Construire des mises en page avec Flexbox et CSS Grid

12 min de lecture
Dans cette leçon5

Bienvenue dans une nouvelle chambre du savoir égyptien ! Je suis Mohamed, et aujourd'hui je vais t'apprendre à construire des mises en page web classiques et avancées en utilisant la puissance de CSS Grid et de Flexbox.

Tout comme les architectes antiques concevaient les différentes parties des pyramides - entrées, chambres, couloirs - nous allons apprendre à concevoir diverses mises en page : de la plus simple à la plus complexe !

Mise en page 1 : le layout Holy Grail

Le Holy Grail est une mise en page classique qui était extrêmement difficile à réaliser avant CSS Grid. Elle se compose de :

  • Header - l'en-tête en haut
  • Footer - le pied de page en bas
  • Main - le contenu principal au centre
  • Nav - la navigation sur le côté gauche
  • Aside - la barre latérale sur le côté droit

Tous ces éléments forment un ensemble harmonieux, un peu comme les couloirs et les chambres d'une pyramide égyptienne !

Implémentation avec CSS Grid :

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>Holy Grail Layout</title>
7  <style>
8    * {
9      margin: 0;
10      padding: 0;
11      box-sizing: border-box;
12    }
13
14    body {
15      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16    }
17
18    .holy-grail {
19      display: grid;
20      grid-template:
21        "header header header" auto
22        "nav main aside" 1fr
23        "footer footer footer" auto
24        / 200px 1fr 200px;
25      min-height: 100vh;
26      gap: 1rem;
27      padding: 1rem;
28    }
29
30    .header {
31      grid-area: header;
32      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
33      color: white;
34      padding: 2rem;
35      text-align: center;
36      border-radius: 8px;
37    }
38
39    .nav {
40      grid-area: nav;
41      background: #f8f9fa;
42      padding: 1.5rem;
43      border-radius: 8px;
44      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
45    }
46
47    .main {
48      grid-area: main;
49      background: white;
50      padding: 2rem;
51      border-radius: 8px;
52      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
53    }
54
55    .aside {
56      grid-area: aside;
57      background: #f8f9fa;
58      padding: 1.5rem;
59      border-radius: 8px;
60      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
61    }
62
63    .footer {
64      grid-area: footer;
65      background: #343a40;
66      color: white;
67      padding: 2rem;
68      text-align: center;
69      border-radius: 8px;
70    }
71
72    /* Responsivité - sur petit écran, la mise en page passe en colonne unique */
73    @media (max-width: 768px) {
74      .holy-grail {
75        grid-template:
76          "header" auto
77          "nav" auto
78          "main" 1fr
79          "aside" auto
80          "footer" auto
81          / 1fr;
82      }
83    }
84
85    .nav ul {
86      list-style: none;
87    }
88
89    .nav li {
90      margin-bottom: 0.5rem;
91    }
92
93    .nav a {
94      color: #495057;
95      text-decoration: none;
96      padding: 0.5rem;
97      display: block;
98      border-radius: 4px;
99      transition: background-color 0.3s;
100    }
101
102    .nav a:hover {
103      background-color: #e9ecef;
104    }
105  </style>
106</head>
107<body>
108  <div class="holy-grail">
109    <header class="header">
110      <h1>Bibliothèque égyptienne du savoir</h1>
111      <p>Découvre les secrets des hiéroglyphes antiques</p>
112    </header>
113
114    <nav class="nav">
115      <h3>Navigation</h3>
116      <ul>
117        <li><a href="#">Accueil</a></li>
118        <li><a href="#">Pyramides</a></li>
119        <li><a href="#">Pharaons</a></li>
120        <li><a href="#">Hiéroglyphes</a></li>
121        <li><a href="#">Mythologie</a></li>
122      </ul>
123    </nav>
124
125    <main class="main">
126      <h2>Bienvenue dans le monde de l'Égypte antique</h2>
127      <p>L'Égypte est une terre pleine de mystères et de merveilles architecturales. Les pyramides, qui ont survécu pendant des milliers d'années, témoignent du savoir et des compétences extraordinaires des bâtisseurs antiques.</p>
128      <p>Ici, tu apprendras les secrets des mises en page web qui - comme les pyramides - se construisent avec précision et harmonie.</p>
129      <h3>Principes de base de la construction d'une mise en page</h3>
130      <ul>
131        <li>La structure doit être stable et prévisible</li>
132        <li>Chaque élément a sa place et sa fonction</li>
133        <li>La responsivité est la clé de l'universalité</li>
134        <li>La simplicité mène à l'élégance</li>
135      </ul>
136    </main>
137
138    <aside class="aside">
139      <h3>Le saviez-vous ?</h3>
140      <p><strong>Le savais-tu...</strong></p>
141      <p>La grande pyramide de Gizeh a été la plus haute structure du monde pendant 3 800 ans ?</p>
142      <p>CSS Grid te permet de créer des mises en page aussi durables que les pyramides !</p>
143    </aside>
144
145    <footer class="footer">
146      <p>&copy; 2024 Académie égyptienne de codage</p>
147      <p>Tous droits réservés par les pharaons</p>
148    </footer>
149  </div>
150</body>
151</html>

Explication du code :

  1. grid-template - définit les zones de la grille sous forme raccourcie :

    • Première ligne : "header header header" auto - l'en-tête s'étend sur 3 colonnes
    • Deuxième ligne : "nav main aside" 1fr - navigation, contenu principal, barre latérale
    • Troisième ligne : "footer footer footer" auto - le pied de page s'étend sur 3 colonnes
    • Après /, on définit la largeur des colonnes : 200px 1fr 200px
  2. grid-area - assigne les éléments aux zones nommées

  3. min-height: 100vh - la mise en page occupe au moins toute la hauteur de l'écran

  4. Media query - sur petit écran, la mise en page passe en colonne unique

Mise en page 2 : le layout Sidebar

Cette mise en page est parfaite pour les tableaux de bord, les panneaux d'administration et les applications web. Elle se compose de :

  • Barre latérale fixe - une navigation qui ne défile pas
  • Contenu défilant - le contenu principal qui défile

Implémentation avec Flexbox + Grid :

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>Sidebar Layout</title>
7  <style>
8    * {
9      margin: 0;
10      padding: 0;
11      box-sizing: border-box;
12    }
13
14    body {
15      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16      overflow: hidden;
17    }
18
19    .sidebar-layout {
20      display: flex;
21      height: 100vh;
22    }
23
24    .sidebar {
25      width: 280px;
26      background: #2c3e50;
27      color: #ecf0f1;
28      display: flex;
29      flex-direction: column;
30      flex-shrink: 0;
31    }
32
33    .sidebar-header {
34      padding: 2rem;
35      background: #34495e;
36      border-bottom: 2px solid #e67e22;
37    }
38
39    .sidebar-header h2 {
40      color: #e67e22;
41      font-size: 1.5rem;
42      margin-bottom: 0.5rem;
43    }
44
45    .sidebar-nav {
46      flex: 1;
47      overflow-y: auto;
48      padding: 1rem 0;
49    }
50
51    .sidebar-nav ul {
52      list-style: none;
53    }
54
55    .sidebar-nav li {
56      margin: 0.25rem 0;
57    }
58
59    .sidebar-nav a {
60      color: #ecf0f1;
61      text-decoration: none;
62      padding: 0.75rem 1.5rem;
63      display: flex;
64      align-items: center;
65      gap: 0.75rem;
66      transition: all 0.3s;
67      border-left: 3px solid transparent;
68    }
69
70    .sidebar-nav a:hover,
71    .sidebar-nav a.active {
72      background: #34495e;
73      border-left-color: #e67e22;
74      padding-left: 2rem;
75    }
76
77    .sidebar-footer {
78      padding: 1.5rem;
79      background: #34495e;
80      border-top: 1px solid #34495e;
81    }
82
83    .main-content {
84      flex: 1;
85      display: flex;
86      flex-direction: column;
87      overflow: hidden;
88    }
89
90    .content-header {
91      background: white;
92      padding: 1.5rem 2rem;
93      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
94      z-index: 10;
95    }
96
97    .content-body {
98      flex: 1;
99      overflow-y: auto;
100      padding: 2rem;
101      background: #f8f9fa;
102    }
103
104    .card {
105      background: white;
106      border-radius: 8px;
107      padding: 1.5rem;
108      margin-bottom: 1.5rem;
109      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
110    }
111
112    .card h3 {
113      color: #2c3e50;
114      margin-bottom: 1rem;
115    }
116
117    /* Responsivité */
118    @media (max-width: 768px) {
119      .sidebar {
120        position: fixed;
121        left: -280px;
122        transition: left 0.3s;
123        z-index: 1000;
124        height: 100vh;
125      }
126
127      .sidebar.open {
128        left: 0;
129      }
130
131      .main-content {
132        width: 100%;
133      }
134    }
135
136    .menu-toggle {
137      display: none;
138      background: #e67e22;
139      color: white;
140      border: none;
141      padding: 0.5rem 1rem;
142      cursor: pointer;
143      border-radius: 4px;
144    }
145
146    @media (max-width: 768px) {
147      .menu-toggle {
148        display: block;
149      }
150    }
151  </style>
152</head>
153<body>
154  <div class="sidebar-layout">
155    <aside class="sidebar" id="sidebar">
156      <div class="sidebar-header">
157        <h2>Panneau du pharaon</h2>
158        <p>Système de gestion de l'empire</p>
159      </div>
160
161      <nav class="sidebar-nav">
162        <ul>
163          <li><a href="#" class="active">Tableau de bord</a></li>
164          <li><a href="#">Pyramides</a></li>
165          <li><a href="#">Sujets</a></li>
166          <li><a href="#">Trésor de l'État</a></li>
167          <li><a href="#">Hiéroglyphes</a></li>
168          <li><a href="#">Art</a></li>
169          <li><a href="#">Armée</a></li>
170          <li><a href="#">Agriculture</a></li>
171          <li><a href="#">Statistiques</a></li>
172          <li><a href="#">Paramètres</a></li>
173        </ul>
174      </nav>
175
176      <div class="sidebar-footer">
177        <p><strong>Pharaon Ramsès II</strong></p>
178        <p style="font-size: 0.875rem; opacity: 0.8;">Souverain des Deux Terres</p>
179      </div>
180    </aside>
181
182    <div class="main-content">
183      <header class="content-header">
184        <button class="menu-toggle" onclick="document.getElementById('sidebar').classList.toggle('open')">
185          Menu
186        </button>
187        <h1>Tableau de bord de l'empire</h1>
188        <p>Bienvenue dans le panneau de gestion de l'État égyptien</p>
189      </header>
190
191      <main class="content-body">
192        <div class="card">
193          <h3>Statistiques de l'empire</h3>
194          <p>Ton empire prospère ! Le nombre de sujets a augmenté de 15 % ce mois-ci.</p>
195        </div>
196
197        <div class="card">
198          <h3>Projets de construction en cours</h3>
199          <ul>
200            <li>Grande pyramide de Gizeh - 75 % terminée</li>
201            <li>Temple de Louxor - 45 % terminé</li>
202            <li>Obélisque de Karnak - 90 % terminé</li>
203          </ul>
204        </div>
205
206        <div class="card">
207          <h3>Derniers décrets</h3>
208          <p>Le pharaon a ordonné la construction d'un nouveau canal d'irrigation dans le delta du Nil.</p>
209        </div>
210
211        <div class="card">
212          <h3>Contenu long pour le défilement</h3>
213          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
214          <p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
215          <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
216        </div>
217      </main>
218    </div>
219  </div>
220</body>
221</html>

Techniques clés du Sidebar Layout :

  1. display: flex - le conteneur principal utilise flexbox pour disposer la barre latérale et le contenu côte à côte
  2. flex-shrink: 0 - la barre latérale ne rétrécit jamais
  3. overflow-y: auto - seul le contenu défile ; la barre latérale reste visible
  4. position: fixed - sur mobile, la barre latérale est masquée et apparaît au clic

Mise en page 3 : la grille de tableau de bord (Card Grid)

La grille de tableau de bord est une mise en page idéale pour les panneaux d'administration où tu as de nombreuses cartes avec différentes informations.

Implémentation avec CSS Grid :

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>Dashboard Grid</title>
7  <style>
8    * {
9      margin: 0;
10      padding: 0;
11      box-sizing: border-box;
12    }
13
14    body {
15      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17      padding: 2rem;
18      min-height: 100vh;
19    }
20
21    .dashboard-header {
22      background: white;
23      padding: 2rem;
24      border-radius: 12px;
25      margin-bottom: 2rem;
26      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
27    }
28
29    .dashboard-header h1 {
30      color: #2c3e50;
31      margin-bottom: 0.5rem;
32    }
33
34    .dashboard-grid {
35      display: grid;
36      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
37      gap: 1.5rem;
38      margin-bottom: 2rem;
39    }
40
41    /* Mises en page particulières pour certaines cartes */
42    .card-large {
43      grid-column: span 2;
44    }
45
46    @media (max-width: 768px) {
47      .card-large {
48        grid-column: span 1;
49      }
50    }
51
52    .card {
53      background: white;
54      border-radius: 12px;
55      padding: 1.5rem;
56      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
57      transition: transform 0.3s, box-shadow 0.3s;
58    }
59
60    .card:hover {
61      transform: translateY(-4px);
62      box-shadow: 0 8px 12px rgba(0,0,0,0.15);
63    }
64
65    .card-header {
66      display: flex;
67      justify-content: space-between;
68      align-items: center;
69      margin-bottom: 1rem;
70      padding-bottom: 1rem;
71      border-bottom: 2px solid #f0f0f0;
72    }
73
74    .card-header h3 {
75      color: #2c3e50;
76      font-size: 1.1rem;
77    }
78
79    .card-icon {
80      font-size: 2rem;
81    }
82
83    .card-stat {
84      font-size: 2.5rem;
85      font-weight: bold;
86      color: #667eea;
87      margin: 1rem 0;
88    }
89
90    .card-label {
91      color: #7f8c8d;
92      font-size: 0.9rem;
93    }
94
95    .card-change {
96      display: inline-block;
97      padding: 0.25rem 0.5rem;
98      border-radius: 4px;
99      font-size: 0.875rem;
100      font-weight: 600;
101    }
102
103    .card-change.positive {
104      background: #d4edda;
105      color: #155724;
106    }
107
108    .card-change.negative {
109      background: #f8d7da;
110      color: #721c24;
111    }
112
113    .chart-placeholder {
114      width: 100%;
115      height: 200px;
116      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
117      border-radius: 8px;
118      display: flex;
119      align-items: center;
120      justify-content: center;
121      color: #7f8c8d;
122      margin-top: 1rem;
123    }
124
125    .activity-list {
126      list-style: none;
127    }
128
129    .activity-item {
130      padding: 0.75rem 0;
131      border-bottom: 1px solid #f0f0f0;
132      display: flex;
133      align-items: center;
134      gap: 1rem;
135    }
136
137    .activity-item:last-child {
138      border-bottom: none;
139    }
140
141    .activity-icon {
142      width: 40px;
143      height: 40px;
144      border-radius: 50%;
145      background: #667eea;
146      color: white;
147      display: flex;
148      align-items: center;
149      justify-content: center;
150      flex-shrink: 0;
151    }
152
153    .activity-content {
154      flex: 1;
155    }
156
157    .activity-title {
158      font-weight: 600;
159      color: #2c3e50;
160      margin-bottom: 0.25rem;
161    }
162
163    .activity-time {
164      font-size: 0.85rem;
165      color: #7f8c8d;
166    }
167  </style>
168</head>
169<body>
170  <div class="dashboard-header">
171    <h1>Tableau de bord de l'empire égyptien</h1>
172    <p>Parcours les indicateurs et statistiques les plus importants</p>
173  </div>
174
175  <div class="dashboard-grid">
176    <!-- Carte 1 : statistiques des sujets -->
177    <div class="card">
178      <div class="card-header">
179        <h3>Sujets</h3>
180        <span class="card-icon">◆</span>
181      </div>
182      <div class="card-stat">2 547 893</div>
183      <div class="card-label">Nombre total de sujets</div>
184      <span class="card-change positive">↑ +12,5 %</span>
185    </div>
186
187    <!-- Carte 2 : pyramides -->
188    <div class="card">
189      <div class="card-header">
190        <h3>Pyramides</h3>
191        <span class="card-icon">◆</span>
192      </div>
193      <div class="card-stat">138</div>
194      <div class="card-label">Pyramides achevées</div>
195      <span class="card-change positive">↑ +3 nouvelles</span>
196    </div>
197
198    <!-- Carte 3 : trésor -->
199    <div class="card">
200      <div class="card-header">
201        <h3>Trésor de l'État</h3>
202        <span class="card-icon">◆</span>
203      </div>
204      <div class="card-stat">45 678</div>
205      <div class="card-label">Talents d'or</div>
206      <span class="card-change negative">↓ -5,2 %</span>
207    </div>
208
209    <!-- Carte 4 : récolte -->
210    <div class="card">
211      <div class="card-header">
212        <h3>Récolte</h3>
213        <span class="card-icon">◆</span>
214      </div>
215      <div class="card-stat">892 456</div>
216      <div class="card-label">Tonnes de grain récoltées</div>
217      <span class="card-change positive">↑ +18,7 %</span>
218    </div>
219
220    <!-- Carte 5 : graphique (grande) -->
221    <div class="card card-large">
222      <div class="card-header">
223        <h3>Croissance de la population des sujets</h3>
224        <span class="card-icon">◆</span>
225      </div>
226      <div class="chart-placeholder">
227        [Graphique en courbe montrant la croissance de la population]
228      </div>
229    </div>
230
231    <!-- Carte 6 : activités récentes -->
232    <div class="card card-large">
233      <div class="card-header">
234        <h3>Événements récents</h3>
235        <span class="card-icon">◆</span>
236      </div>
237      <ul class="activity-list">
238        <li class="activity-item">
239          <div class="activity-icon">◆</div>
240          <div class="activity-content">
241            <div class="activity-title">Construction de la pyramide de Gizeh achevée</div>
242            <div class="activity-time">il y a 2 heures</div>
243          </div>
244        </li>
245        <li class="activity-item">
246          <div class="activity-icon">◆</div>
247          <div class="activity-content">
248            <div class="activity-title">Victoire à la bataille du Nil</div>
249            <div class="activity-time">il y a 5 heures</div>
250          </div>
251        </li>
252        <li class="activity-item">
253          <div class="activity-icon">◆</div>
254          <div class="activity-content">
255            <div class="activity-title">Nouveau décret du pharaon annoncé</div>
256            <div class="activity-time">il y a 1 jour</div>
257          </div>
258        </li>
259        <li class="activity-item">
260          <div class="activity-icon">◆</div>
261          <div class="activity-content">
262            <div class="activity-title">La saison des récoltes a commencé</div>
263            <div class="activity-time">il y a 2 jours</div>
264          </div>
265        </li>
266      </ul>
267    </div>
268  </div>
269</body>
270</html>

Techniques clés de la grille de tableau de bord :

  1. repeat(auto-fit, minmax(300px, 1fr)) - ajustement automatique du nombre de colonnes
  2. grid-column: span 2 - certaines cartes s'étendent sur 2 colonnes (plus larges)
  3. gap: 1.5rem - espacement entre les cartes
  4. Responsivité - passage automatique en colonne unique sur petit écran

Comparaison : quand utiliser Grid ou Flexbox ?

Utilise CSS Grid quand :

  • Tu as besoin d'une mise en page bidimensionnelle (lignes ET colonnes)
  • Tu as une mise en page complexe avec de nombreuses sections (Holy Grail, Dashboard)
  • Tu veux contrôler précisément la position des éléments
  • Tu as besoin de zones qui se chevauchent

Utilise Flexbox quand :

  • Tu travailles avec une mise en page unidimensionnelle (uniquement des lignes OU des colonnes)
  • Tu disposes des éléments en ligne (barre de navigation, listes)
  • Tu as besoin d'une mise en page dynamique qui s'adapte au contenu
  • Tu construis des composants (cartes, boutons, formulaires)

La meilleure combinaison - Grid + Flexbox :

1/* Grid pour la mise en page principale */
2.page {
3  display: grid;
4  grid-template:
5    "header" auto
6    "content" 1fr
7    "footer" auto
8    / 1fr;
9}
10
11/* Flexbox pour les composants internes */
12.header {
13  display: flex;
14  justify-content: space-between;
15  align-items: center;
16}
17
18.nav {
19  display: flex;
20  gap: 1rem;
21}

Résumé

Tout comme les pyramides égyptiennes sont composées de blocs de pierre disposés avec précision, les sites web modernes sont composés de mises en page bien pensées :

  1. Holy Grail Layout - mise en page classique avec header, footer, nav, main, aside
  2. Sidebar Layout - idéal pour les tableaux de bord et les panneaux
  3. Dashboard Grid - grille de cartes flexible

Chacune de ces mises en page a son cas d'usage, et tu peux les combiner pour créer d'excellentes interfaces utilisateur !

Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head><title>Nav et Main</title></head>
4<body style="background:#d4a574;font-family:serif;padding:20px;color:#3d2914">
5<h1>Nav et Main</h1>
6<nav>Navigation - les couloirs des pyramides</nav>
7<main>Chambre principale du pharaon</main>
8</body>
9</html>

Bonne chance dans la construction de tes pyramides numériques, jeune architecte !

Emporte cette idée en quittant la chambre : CSS Grid trace le plan de l'édifice entier en deux dimensions à la fois - header, nav, main, aside et footer - tandis que Flexbox ordonne ce qui se trouve à l'intérieur d'une seule salle, et ce sont les architectes qui combinent les deux outils qui bâtissent les mises en page les plus solides.

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. Quelle est la différence entre auto-fill et auto-fit dans repeat() ?

  2. 2. À quoi sert la propriété grid-area sur un élément enfant ?

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Ordonne les propriétés du conteneur CSS Grid dans l'ordre de définition d'une mise en page Grid :

  • Éditeur de code

    Utilise des lignes nommées [sidebar-start] [main-start] [main-end] pour positionner précisément les éléments dans la grille.

  • Tri horizontal

    Ordonne la définition de colonnes CSS Grid avec des lignes nommées :

  • Clique dans l'ordre

    Ordonne la déclaration grid-template-areas avec un header, un contenu et un footer

Articles utiles