Cours HTML et CSS · Module 9: CSS moderne
Container Queries - La réactivité basée sur le conteneur
Dans cette leçon6
Ta carte d'artefact a fière allure dans la large colonne de la galerie, mais dans l'étroit panneau latéral, elle se déforme, et la media query ne remarque rien, car la fenêtre du navigateur n'a pas changé. La carte ne sait pas dans quelle chambre elle se trouve. Les Container Queries sont une fonctionnalité CSS qui permet de créer des composants responsive en fonction de la taille de leur conteneur, plutôt que de la fenêtre du navigateur. C'est une avancée majeure qui permet des mises en page véritablement modulaires.
Ce que tu vas apprendre
- transformer un élément en conteneur et écrire une requête
@container, - nommer des conteneurs et combiner des conditions avec des opérateurs,
- distinguer les tâches des Container Queries de celles des media queries,
- utiliser les unités de conteneur, comme
cqw.
Les bases des Container Queries
Que sont les Container Queries ?
Les Container Queries te permettent d'appliquer des styles en fonction de la taille du conteneur parent, et non du viewport, les composants réagissent donc à leur contexte local. Compare les deux requêtes :
1/* Media Queries traditionnelles - basées sur le viewport */
2@media (max-width: 768px) {
3 .card {
4 flex-direction: column;
5 }
6}
7
8/* Container Queries - basées sur la taille du conteneur */
9@container (max-width: 400px) {
10 .card {
11 flex-direction: column;
12 }
13}Les deux règles disposent la carte en colonne. La syntaxe des conditions reste la même, seul le point de référence change : la fenêtre ou le conteneur.
Définir un contexte de conteneur
Pour utiliser les Container Queries, nous devons d'abord définir un élément comme conteneur avec la propriété container-type :
1.container {
2 container-type: inline-size; /* Surveille la largeur */
3}
4
5.container {
6 container-type: size; /* Surveille la largeur et la hauteur */
7}
8
9.container {
10 container-type: normal; /* Valeur par défaut - aucune surveillance */
11}
12
13/* Forme abrégée avec un nom de conteneur */
14.sidebar {
15 container: sidebar / inline-size;
16}inline-size suit la largeur et suffit presque toujours. size suit aussi la hauteur, mais l'élément cesse alors de tirer sa hauteur de son contenu. La règle la plus importante : un élément ne peut pas s'interroger lui-même, donc les règles dans @container stylent les descendants du conteneur. L'ordre de travail : container-type sur le parent, un nom facultatif dans container-name, la requête @container, les styles des enfants et un test à différentes largeurs.
Applications pratiques des Container Queries
1. Carte produit réactive
Ici, le conteneur est toute la grille de produits, et les cartes sont ses descendantes, qui changent de disposition en même temps qu'elle :
1.product-grid {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
4 gap: 1rem;
5 container-type: inline-size;
6}
7
8.product-card {
9 background: white;
10 border-radius: 8px;
11 padding: 1rem;
12 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
13}
14
15/* Lorsque le conteneur est étroit - disposition verticale */
16@container (max-width: 300px) {
17 .product-card {
18 text-align: center;
19 }
20
21 .product-card .image {
22 width: 100%;
23 margin-bottom: 1rem;
24 }
25
26 .product-card .title {
27 font-size: 1.1rem;
28 margin-bottom: 0.5rem;
29 }
30
31 .product-card .price {
32 font-size: 1.2rem;
33 color: #e74c3c;
34 }
35}
36
37/* Lorsque le conteneur est plus large - disposition horizontale */
38@container (min-width: 400px) {
39 .product-card {
40 display: flex;
41 align-items: center;
42 gap: 1rem;
43 }
44
45 .product-card .image {
46 width: 120px;
47 height: 120px;
48 flex-shrink: 0;
49 }
50
51 .product-card .content {
52 flex: 1;
53 }
54
55 .product-card .title {
56 font-size: 1.3rem;
57 margin-bottom: 0.5rem;
58 }
59
60 .product-card .description {
61 color: #666;
62 margin-bottom: 1rem;
63 }
64
65 .product-card .price {
66 font-size: 1.4rem;
67 font-weight: bold;
68 color: #27ae60;
69 }
70}On interroge la largeur de toute la grille, et non celle d'une seule carte. Si chaque carte doit réagir séparément, fais de son enveloppe le conteneur.
2. Navigation adaptative
Tu peux nommer un conteneur, et la requête @container nav n'interroge alors que ce conteneur, même si un autre se trouve plus près :
1.navigation {
2 container-name: nav;
3 container-type: inline-size;
4}
5
6.nav-list {
7 display: flex;
8 list-style: none;
9 margin: 0;
10 padding: 0;
11 gap: 1rem;
12}
13
14/* Navigation compacte pour les petits conteneurs */
15@container nav (max-width: 600px) {
16 .nav-list {
17 flex-direction: column;
18 gap: 0;
19 }
20
21 .nav-item {
22 border-bottom: 1px solid #eee;
23 }
24
25 .nav-link {
26 display: block;
27 padding: 1rem;
28 text-decoration: none;
29 transition: background-color 0.2s;
30 }
31
32 .nav-link:hover {
33 background-color: #f8f9fa;
34 }
35
36 /* Masquer le texte et n'afficher que les icônes */
37 .nav-text {
38 display: none;
39 }
40
41 .nav-icon {
42 display: block;
43 font-size: 1.5rem;
44 }
45}
46
47/* Navigation complète pour les conteneurs plus grands */
48@container nav (min-width: 601px) {
49 .nav-list {
50 justify-content: space-between;
51 align-items: center;
52 }
53
54 .nav-link {
55 display: flex;
56 align-items: center;
57 gap: 0.5rem;
58 padding: 0.5rem 1rem;
59 text-decoration: none;
60 border-radius: 4px;
61 transition: all 0.2s;
62 }
63
64 .nav-link:hover {
65 background-color: #007bff;
66 color: white;
67 }
68
69 .nav-text {
70 display: inline;
71 }
72
73 .nav-icon {
74 font-size: 1.2rem;
75 }
76}Jusqu'à 600px, la navigation devient une liste verticale d'icônes, et à partir de 601px, elle affiche les liens complets avec leur texte.
3. Tableau de bord avec widgets flexibles
Dans le tableau de bord, chaque widget est lui-même un conteneur, il affichera donc plus ou moins de détails selon qu'il se trouve dans une colonne étroite ou large :
1.dashboard {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4 gap: 1rem;
5 padding: 1rem;
6}
7
8.widget {
9 background: white;
10 border-radius: 8px;
11 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
12 container-type: inline-size;
13 overflow: hidden;
14}
15
16.widget-header {
17 padding: 1rem;
18 background: #f8f9fa;
19 border-bottom: 1px solid #dee2e6;
20}
21
22.widget-content {
23 padding: 1rem;
24}
25
26/* Petit widget - informations de base */
27@container (max-width: 350px) {
28 .widget-header h3 {
29 font-size: 1rem;
30 margin: 0;
31 }
32
33 .widget-stats {
34 display: block;
35 }
36
37 .stat-item {
38 margin-bottom: 0.5rem;
39 text-align: center;
40 }
41
42 .stat-value {
43 font-size: 1.5rem;
44 font-weight: bold;
45 display: block;
46 }
47
48 .stat-label {
49 font-size: 0.8rem;
50 color: #666;
51 }
52
53 .chart {
54 height: 150px;
55 }
56}
57
58/* Widget moyen - plus de détails */
59@container (min-width: 351px) and (max-width: 500px) {
60 .widget-header h3 {
61 font-size: 1.2rem;
62 margin: 0;
63 }
64
65 .widget-stats {
66 display: flex;
67 justify-content: space-around;
68 margin-bottom: 1rem;
69 }
70
71 .stat-item {
72 text-align: center;
73 }
74
75 .stat-value {
76 font-size: 1.8rem;
77 font-weight: bold;
78 display: block;
79 color: #007bff;
80 }
81
82 .stat-label {
83 font-size: 0.9rem;
84 color: #666;
85 }
86
87 .chart {
88 height: 200px;
89 }
90}
91
92/* Grand widget - détails complets */
93@container (min-width: 501px) {
94 .widget-header {
95 display: flex;
96 justify-content: space-between;
97 align-items: center;
98 }
99
100 .widget-header h3 {
101 font-size: 1.4rem;
102 margin: 0;
103 }
104
105 .widget-actions {
106 display: flex;
107 gap: 0.5rem;
108 }
109
110 .widget-stats {
111 display: grid;
112 grid-template-columns: repeat(3, 1fr);
113 gap: 1rem;
114 margin-bottom: 1.5rem;
115 }
116
117 .stat-item {
118 text-align: center;
119 padding: 1rem;
120 background: #f8f9fa;
121 border-radius: 4px;
122 }
123
124 .stat-value {
125 font-size: 2rem;
126 font-weight: bold;
127 display: block;
128 color: #28a745;
129 }
130
131 .stat-label {
132 font-size: 1rem;
133 color: #666;
134 margin-top: 0.5rem;
135 }
136
137 .chart {
138 height: 250px;
139 }
140
141 .widget-details {
142 display: block;
143 margin-top: 1rem;
144 padding-top: 1rem;
145 border-top: 1px solid #dee2e6;
146 }
147}Les trois plages ne se chevauchent pas, c'est pourquoi un seul ensemble de styles s'applique à chaque fois.
Techniques avancées des Container Queries
1. Opérateurs logiques
Tu combines les conditions avec les mots and, or et not, comme dans les media queries. Ici, le conteneur est le parent du composant :
1.component-wrapper {
2 container-type: inline-size; /* le parent est le conteneur */
3}
4
5/* Combiner des conditions */
6@container (min-width: 300px) and (max-width: 600px) {
7 .component {
8 background: lightblue;
9 }
10}
11
12/* Alternative */
13@container (max-width: 300px) or (min-width: 800px) {
14 .component {
15 border: 2px solid red;
16 }
17}
18
19/* Négation */
20@container not (min-width: 400px) {
21 .component {
22 font-size: 0.9rem;
23 }
24}L'enveloppe est le conteneur, car .component ne pourrait pas s'interroger lui-même. La troisième règle s'applique chaque fois que le conteneur est plus étroit que 400px.
2. Conteneurs imbriqués
Plusieurs conteneurs peuvent fonctionner en même temps sur une page, l'un dans l'autre, et les noms indiquent lequel tu interroges :
1.main-container {
2 container-name: main;
3 container-type: inline-size;
4}
5
6.sidebar {
7 container-name: sidebar;
8 container-type: inline-size;
9}
10
11.article {
12 container-name: article;
13 container-type: inline-size;
14}
15
16/* Styles différents selon le contexte */
17@container main (min-width: 1200px) {
18 .layout {
19 display: grid;
20 grid-template-columns: 300px 1fr;
21 gap: 2rem;
22 }
23}
24
25@container sidebar (max-width: 250px) {
26 .sidebar-item {
27 padding: 0.5rem;
28 }
29
30 .sidebar-text {
31 display: none;
32 }
33}
34
35@container article (min-width: 600px) {
36 .article-content {
37 columns: 2;
38 column-gap: 2rem;
39 }
40}Une requête avec un nom cherche l'ancêtre le plus proche portant ce nom, et une requête sans nom prend le conteneur le plus proche, quel qu'il soit.
3. Container Queries avec CSS Grid
Les Container Queries se combinent parfaitement avec Grid. La galerie a de une à quatre colonnes, selon la largeur de son enveloppe :
1.gallery-wrapper {
2 container-type: inline-size; /* l'enveloppe de la galerie est le conteneur */
3}
4
5/* Galerie réactive basée sur la taille du conteneur */
6@container (max-width: 400px) {
7 .gallery {
8 display: grid;
9 grid-template-columns: 1fr;
10 gap: 1rem;
11 }
12}
13
14@container (min-width: 401px) and (max-width: 800px) {
15 .gallery {
16 display: grid;
17 grid-template-columns: repeat(2, 1fr);
18 gap: 1rem;
19 }
20}
21
22@container (min-width: 801px) and (max-width: 1200px) {
23 .gallery {
24 display: grid;
25 grid-template-columns: repeat(3, 1fr);
26 gap: 1.5rem;
27 }
28}
29
30@container (min-width: 1201px) {
31 .gallery {
32 display: grid;
33 grid-template-columns: repeat(4, 1fr);
34 gap: 2rem;
35 }
36}
37
38/* Images adaptatives */
39.gallery-item {
40 position: relative;
41 overflow: hidden;
42 border-radius: 8px;
43}
44
45@container (max-width: 400px) {
46 .gallery-item {
47 aspect-ratio: 16/9;
48 }
49
50 .gallery-item img {
51 width: 100%;
52 height: 100%;
53 object-fit: cover;
54 }
55
56 .gallery-caption {
57 position: absolute;
58 bottom: 0;
59 left: 0;
60 right: 0;
61 background: linear-gradient(transparent, rgba(0,0,0,0.8));
62 color: white;
63 padding: 1rem;
64 font-size: 0.9rem;
65 }
66}
67
68@container (min-width: 801px) {
69 .gallery-item {
70 aspect-ratio: 1;
71 transition: transform 0.3s ease;
72 }
73
74 .gallery-item:hover {
75 transform: scale(1.05);
76 }
77
78 .gallery-caption {
79 position: absolute;
80 bottom: 0;
81 left: 0;
82 right: 0;
83 background: rgba(0,0,0,0.9);
84 color: white;
85 padding: 1rem;
86 transform: translateY(100%);
87 transition: transform 0.3s ease;
88 }
89
90 .gallery-item:hover .gallery-caption {
91 transform: translateY(0);
92 }
93}Le conteneur est .gallery-wrapper, car la galerie ne peut pas interroger sa propre largeur. Dans un conteneur large, les photos deviennent des carrés avec une légende qui glisse au survol du curseur.
Container Queries vs Media Queries
Quand utiliser les Container Queries ?
Les deux techniques se complètent : les Container Queries servent aux composants, et les media queries aux changements de toute la page :
1/* Bon usage des Container Queries */
2.component {
3 container-type: inline-size;
4}
5
6/* Composants pouvant être utilisés dans différents contextes */
7@container (max-width: 300px) {
8 .card {
9 /* Styles pour un conteneur étroit */
10 flex-direction: column;
11 }
12}
13
14/* Media Queries pour les changements globaux */
15@media (max-width: 768px) {
16 body {
17 font-size: 14px;
18 }
19
20 .global-header {
21 padding: 1rem;
22 }
23}
24
25/* N'utilise pas les Container Queries pour des changements globaux */
26@container (max-width: 768px) {
27 body { /* Cela ne fonctionnera pas comme prévu */
28 font-size: 14px;
29 }
30}La dernière règle ne fonctionnera pas, car body n'a aucun conteneur au-dessus de lui. Laisse les changements globaux aux media queries.
Exemple pratique - Carte modulaire
Le même HTML de carte de profil se trouve une fois dans la large colonne principale, et une fois dans l'étroit panneau latéral :
1<!-- HTML -->
2<div class="page-layout">
3 <main class="main-content">
4 <div class="card-container">
5 <div class="profile-card">
6 <img src="avatar.jpg" alt="Profil" class="avatar">
7 <div class="info">
8 <h3 class="name">John Smith</h3>
9 <p class="role">Développeur Frontend</p>
10 <p class="description">Passionné par la création d'expériences web exceptionnelles</p>
11 <div class="actions">
12 <button class="btn primary">Suivre</button>
13 <button class="btn secondary">Message</button>
14 </div>
15 </div>
16 </div>
17 </div>
18 </main>
19
20 <aside class="sidebar">
21 <div class="card-container">
22 <div class="profile-card">
23 <!-- Même carte, mais dans un conteneur plus étroit -->
24 <img src="avatar.jpg" alt="Profil" class="avatar">
25 <div class="info">
26 <h3 class="name">John Smith</h3>
27 <p class="role">Développeur Frontend</p>
28 <p class="description">Passionné par la création d'expériences web exceptionnelles</p>
29 <div class="actions">
30 <button class="btn primary">Suivre</button>
31 <button class="btn secondary">Message</button>
32 </div>
33 </div>
34 </div>
35 </div>
36 </aside>
37</div>Les deux copies ont un code identique. Les styles ci-dessous feront en sorte que chaque carte s'adapte à son conteneur .card-container :
1/* CSS avec Container Queries */
2.card-container {
3 container-type: inline-size;
4}
5
6.profile-card {
7 background: white;
8 border-radius: 12px;
9 padding: 1.5rem;
10 box-shadow: 0 4px 6px rgba(0,0,0,0.1);
11 transition: all 0.3s ease;
12}
13
14/* Conteneur étroit - disposition verticale */
15@container (max-width: 350px) {
16 .profile-card {
17 text-align: center;
18 }
19
20 .avatar {
21 width: 80px;
22 height: 80px;
23 border-radius: 50%;
24 margin: 0 auto 1rem;
25 display: block;
26 }
27
28 .name {
29 font-size: 1.2rem;
30 margin-bottom: 0.5rem;
31 }
32
33 .role {
34 color: #666;
35 font-size: 0.9rem;
36 margin-bottom: 1rem;
37 }
38
39 .description {
40 display: none; /* Masquer dans un conteneur étroit */
41 }
42
43 .actions {
44 display: flex;
45 flex-direction: column;
46 gap: 0.5rem;
47 }
48
49 .btn {
50 padding: 0.75rem;
51 border: none;
52 border-radius: 6px;
53 font-size: 0.9rem;
54 cursor: pointer;
55 transition: all 0.2s;
56 }
57
58 .btn.primary {
59 background: #007bff;
60 color: white;
61 }
62
63 .btn.secondary {
64 background: #f8f9fa;
65 color: #666;
66 }
67}
68
69/* Conteneur moyen - disposition mixte */
70@container (min-width: 351px) and (max-width: 500px) {
71 .profile-card {
72 display: flex;
73 align-items: center;
74 gap: 1rem;
75 text-align: left;
76 }
77
78 .avatar {
79 width: 100px;
80 height: 100px;
81 border-radius: 50%;
82 flex-shrink: 0;
83 }
84
85 .info {
86 flex: 1;
87 }
88
89 .name {
90 font-size: 1.3rem;
91 margin-bottom: 0.25rem;
92 }
93
94 .role {
95 color: #666;
96 font-size: 1rem;
97 margin-bottom: 0.5rem;
98 }
99
100 .description {
101 font-size: 0.9rem;
102 color: #888;
103 margin-bottom: 1rem;
104 display: -webkit-box;
105 -webkit-line-clamp: 2;
106 -webkit-box-orient: vertical;
107 overflow: hidden;
108 }
109
110 .actions {
111 display: flex;
112 gap: 0.5rem;
113 }
114
115 .btn {
116 padding: 0.5rem 1rem;
117 border: none;
118 border-radius: 6px;
119 font-size: 0.9rem;
120 cursor: pointer;
121 transition: all 0.2s;
122 }
123
124 .btn.primary {
125 background: #007bff;
126 color: white;
127 }
128
129 .btn.secondary {
130 background: #f8f9fa;
131 color: #666;
132 border: 1px solid #dee2e6;
133 }
134}
135
136/* Conteneur large - disposition complète */
137@container (min-width: 501px) {
138 .profile-card {
139 display: flex;
140 align-items: flex-start;
141 gap: 1.5rem;
142 }
143
144 .avatar {
145 width: 120px;
146 height: 120px;
147 border-radius: 50%;
148 flex-shrink: 0;
149 }
150
151 .info {
152 flex: 1;
153 }
154
155 .name {
156 font-size: 1.5rem;
157 margin-bottom: 0.5rem;
158 font-weight: 600;
159 }
160
161 .role {
162 color: #007bff;
163 font-size: 1.1rem;
164 margin-bottom: 1rem;
165 font-weight: 500;
166 }
167
168 .description {
169 font-size: 1rem;
170 color: #555;
171 line-height: 1.6;
172 margin-bottom: 1.5rem;
173 }
174
175 .actions {
176 display: flex;
177 gap: 1rem;
178 }
179
180 .btn {
181 padding: 0.75rem 1.5rem;
182 border: none;
183 border-radius: 8px;
184 font-size: 1rem;
185 font-weight: 500;
186 cursor: pointer;
187 transition: all 0.2s;
188 }
189
190 .btn.primary {
191 background: #007bff;
192 color: white;
193 }
194
195 .btn.primary:hover {
196 background: #0056b3;
197 }
198
199 .btn.secondary {
200 background: white;
201 color: #666;
202 border: 2px solid #dee2e6;
203 }
204
205 .btn.secondary:hover {
206 border-color: #007bff;
207 color: #007bff;
208 }
209}Dans le panneau, la carte se dispose verticalement et masque la description, tandis que dans la colonne principale, elle affiche tout, sans une seule media query.
Bonnes pratiques des Container Queries
1. Performance et optimisation
Choisis le type de conteneur le plus restreint dont tu as besoin, regroupe les règles qui partagent les mêmes seuils et évite d'imbriquer les requêtes :
1/* N'utilise que le type de conteneur nécessaire */
2.width-only {
3 container-type: inline-size; /* Meilleur pour les performances */
4}
5
6.both-dimensions {
7 container-type: size; /* Uniquement quand tu as besoin de la hauteur */
8}
9
10/* Regroupe les points de rupture similaires */
11@container (max-width: 400px) {
12 .component-a { /* styles */ }
13 .component-b { /* styles */ }
14 .component-c { /* styles */ }
15}
16
17/* Évite une imbrication excessive */
18@container (min-width: 300px) {
19 @container (max-width: 600px) { /* Difficile à gérer */
20 .component { /* styles */ }
21 }
22}Un @container imbriqué est valide, mais difficile à lire, alors combine plutôt les conditions avec l'opérateur and.
2. Solution de repli pour les navigateurs anciens
Les Container Queries fonctionnent dans tous les principaux navigateurs depuis 2023, et @supports permet de les ajouter comme une amélioration :
1/* Repli sans Container Queries */
2.responsive-component {
3 padding: 1rem;
4 background: #f8f9fa;
5}
6
7.responsive-component .title {
8 font-size: 1.2rem;
9 margin-bottom: 1rem;
10}
11
12.responsive-component .content {
13 display: block;
14}
15
16/* Container Queries comme amélioration */
17@supports (container-type: inline-size) {
18 .responsive-container {
19 container-type: inline-size;
20 }
21
22 @container (min-width: 400px) {
23 .responsive-component {
24 padding: 2rem;
25 }
26
27 .responsive-component .title {
28 font-size: 1.5rem;
29 }
30
31 .responsive-component .content {
32 display: flex;
33 gap: 1rem;
34 }
35 }
36}Chaque navigateur reçoit les styles de base, et les plus récents obtiennent en plus la disposition qui dépend du conteneur. Rien ne casse.
Unités des Container Queries
Les Container Queries introduisent des unités spéciales qui font référence à la taille du conteneur :
| Unité | Description |
|---|---|
cqw | 1 % de la largeur du conteneur (container query width) |
cqh | 1 % de la hauteur du conteneur (container query height) |
cqi | 1 % de la taille inline du conteneur (container query inline) |
cqb | 1 % de la taille block du conteneur (container query block) |
Utilisons l'unité cqw pour que le titre de la carte grandisse avec son conteneur :
1@container (min-width: 400px) {
2 .card-title {
3 font-size: 5cqw; /* 5 % de la largeur du conteneur */
4 }
5}Ces unités fonctionnent comme vw et vh, mais par rapport au conteneur. Quand un élément n'a aucun conteneur au-dessus de lui, elles se calculent par rapport à la fenêtre.
Mon conseil : réserve les media queries à la mise en page, et construis les composants avec les Container Queries. Plus loin dans ce module, tu découvriras le sélecteur :has(), qui style un parent en fonction de ses enfants et forme avec les Container Queries le duo de la responsivité moderne. Dans le bac à sable ci-dessous, ajoute container-type: inline-size à .card-container et observe la carte.
Souviens-toi : une media query demande la taille de tout le palais, et une container query celle de la chambre où se trouve ton composant.
Code de cette leçon : index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Container Queries</title>
6 <link rel="stylesheet" href="style.css">
7</head>
8<body>
9 <h1>Container Queries</h1>
10 <div class="wide-wrapper">
11 <div class="card-container">
12 <div class="card">
13 <div class="card-img">IMG</div>
14 <div class="card-body">
15 <h2>Scarabée</h2>
16 <p>Symbole de la renaissance dans l'Égypte ancienne.</p>
17 </div>
18 </div>
19 </div>
20 </div>
21 <div class="narrow-wrapper">
22 <div class="card-container">
23 <div class="card">
24 <div class="card-img">IMG</div>
25 <div class="card-body">
26 <h2>Ankh</h2>
27 <p>La clé de vie - symbole de l'éternité.</p>
28 </div>
29 </div>
30 </div>
31 </div>
32</body>
33</html>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. Que sont les Container Queries en CSS ?
2. Comment définit-on un conteneur pour les Container Queries ?
Tâches pratiques dans le jeu
- Éditeur de code
Crée .card-container { container-type: inline-size }. À l'intérieur, ajoute une .card qui change sa flex-direction de column à row à @container (min-width: 300px). Place-la à différentes largeurs - la carte s'adaptera !