Create flexible grid systems that adapt to any screen size seamlessly using modern CSS Grid and Flexbox techniques.
Flexible grid systems are the foundation of modern responsive web design. Unlike traditional fixed grids, flexible grids adapt automatically to different screen sizes, creating layouts that work seamlessly across all devices.
CSS Grid has revolutionized how we build responsive layouts, offering powerful features like automatic sizing, content-aware grids, and intrinsic web design. Combined with Flexbox for component-level layouts, you can create sophisticated grid systems that require minimal media queries.
In this lesson, you'll learn to create truly flexible grids that respond to content and container size, making your designs both responsive and maintainable.
CSS Grid provides powerful tools for creating responsive layouts that adapt automatically to content and screen size.
Auto-Responsive Grid Features:
Basic Responsive Grid Pattern:
1.grid-container {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4 gap: 2rem;
5}This creates a grid that:
Advanced Grid Techniques:
Create reusable grid components that adapt to any context and content.
Card Grid System:
1.card-grid {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
4 gap: 1.5rem;
5 padding: 2rem;
6}
7
8.card-grid--dense {
9 grid-auto-flow: row dense;
10 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
11}Responsive Article Layout:
1.article-layout {
2 display: grid;
3 grid-template-columns:
4 minmax(1rem, 1fr)
5 minmax(0, 65ch)
6 minmax(1rem, 1fr);
7 grid-template-rows: auto 1fr auto;
8}
9
10.article-layout > * {
11 grid-column: 2;
12}
13
14.article-layout .full-width {
15 grid-column: 1 / -1;
16}Gallery Grid with Varying Sizes:
1.gallery-grid {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
4 grid-auto-rows: 250px;
5 gap: 1rem;
6}
7
8.gallery-item:nth-child(3n) {
9 grid-row: span 2;
10}
11
12.gallery-item:nth-child(5n) {
13 grid-column: span 2;
14}Benefits:
Master advanced techniques for creating sophisticated responsive grid systems.
Holy Grail Layout (Grid Version):
1.holy-grail {
2 display: grid;
3 grid-template:
4 "header header header" auto
5 "nav main aside" 1fr
6 "footer footer footer" auto
7 / 200px 1fr 200px;
8 min-height: 100vh;
9 gap: 1rem;
10}
11
12@media (max-width: 768px) {
13 .holy-grail {
14 grid-template:
15 "header" auto
16 "nav" auto
17 "main" 1fr
18 "aside" auto
19 "footer" auto
20 / 1fr;
21 }
22}Masonry-Style Grid:
1.masonry-grid {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4 grid-auto-rows: 10px;
5 gap: 1rem;
6}
7
8.masonry-item {
9 border-radius: 8px;
10 padding: 1rem;
11 background: white;
12 box-shadow: 0 2px 8px rgba(0,0,0,0.1);
13}
14
15/* JavaScript calculates grid-row-end based on content height */Responsive Dashboard Grid:
1.dashboard-grid {
2 display: grid;
3 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
4 grid-auto-rows: minmax(200px, auto);
5 gap: 2rem;
6 padding: 2rem;
7}
8
9.dashboard-item {
10 background: white;
11 border-radius: 12px;
12 padding: 2rem;
13 box-shadow: 0 4px 12px rgba(0,0,0,0.05);
14 display: flex;
15 flex-direction: column;
16}
17
18.dashboard-item--large {
19 grid-column: span 2;
20}
21
22.dashboard-item--tall {
23 grid-row: span 2;
24}
25
26@media (max-width: 768px) {
27 .dashboard-item--large,
28 .dashboard-item--tall {
29 grid-column: span 1;
30 grid-row: span 1;
31 }
32}Container-Query Responsive Grids:
1.flexible-container {
2 container-type: inline-size;
3}
4
5.responsive-grid {
6 display: grid;
7 gap: 1rem;
8 grid-template-columns: 1fr;
9}
10
11@container (min-width: 400px) {
12 .responsive-grid {
13 grid-template-columns: 1fr 1fr;
14 }
15}
16
17@container (min-width: 600px) {
18 .responsive-grid {
19 grid-template-columns: repeat(3, 1fr);
20 }
21}
22
23@container (min-width: 900px) {
24 .responsive-grid {
25 grid-template-columns: repeat(4, 1fr);
26 }
27}These patterns provide:
Create a comprehensive grid system that works for cards, galleries, and complex layouts.
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>Flexible Grid Systems</title>
7 <style>
8 * {
9 margin: 0;
10 padding: 0;
11 box-sizing: border-box;
12 }
13
14 body {
15 font-family: 'Arial', sans-serif;
16 line-height: 1.6;
17 color: #333;
18 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
19 min-height: 100vh;
20 padding: 2rem;
21 }
22
23 .container {
24 max-width: 1400px;
25 margin: 0 auto;
26 background: rgba(255, 255, 255, 0.95);
27 border-radius: 20px;
28 padding: 3rem;
29 box-shadow: 0 20px 40px rgba(0,0,0,0.1);
30 }
31
32 .section {
33 margin-bottom: 4rem;
34 }
35
36 .section-title {
37 font-size: 2rem;
38 margin-bottom: 1rem;
39 color: #2c3e50;
40 text-align: center;
41 position: relative;
42 }
43
44 .section-title::after {
45 content: '';
46 display: block;
47 width: 60px;
48 height: 3px;
49 background: linear-gradient(45deg, #667eea, #764ba2);
50 margin: 0.5rem auto;
51 border-radius: 2px;
52 }
53
54 /* Auto-Responsive Card Grid */
55 .auto-grid {
56 display: grid;
57 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
58 gap: 2rem;
59 margin: 2rem 0;
60 }
61
62 .card {
63 background: white;
64 border-radius: 12px;
65 padding: 2rem;
66 box-shadow: 0 8px 25px rgba(0,0,0,0.1);
67 transition: all 0.3s ease;
68 border: 1px solid #e2e8f0;
69 position: relative;
70 overflow: hidden;
71 }
72
73 .card::before {
74 content: '';
75 position: absolute;
76 top: 0;
77 left: 0;
78 right: 0;
79 height: 4px;
80 background: linear-gradient(45deg, #667eea, #764ba2);
81 }
82
83 .card:hover {
84 transform: translateY(-5px);
85 box-shadow: 0 15px 35px rgba(0,0,0,0.15);
86 }
87
88 .card-title {
89 font-size: 1.25rem;
90 font-weight: bold;
91 margin-bottom: 1rem;
92 color: #2c3e50;
93 }
94
95 .card-content {
96 color: #64748b;
97 line-height: 1.6;
98 }
99
100 /* Gallery Grid with Flexible Sizing */
101 .gallery-grid {
102 display: grid;
103 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
104 grid-auto-rows: 200px;
105 gap: 1rem;
106 margin: 2rem 0;
107 }
108
109 .gallery-item {
110 background: linear-gradient(135deg,
111 rgba(102, 126, 234, 0.8),
112 rgba(118, 75, 162, 0.8));
113 border-radius: 12px;
114 display: flex;
115 align-items: center;
116 justify-content: center;
117 color: white;
118 font-weight: bold;
119 font-size: 1.1rem;
120 text-shadow: 0 2px 4px rgba(0,0,0,0.3);
121 transition: all 0.3s ease;
122 position: relative;
123 overflow: hidden;
124 }
125
126 .gallery-item::before {
127 content: '';
128 position: absolute;
129 top: -50%;
130 left: -50%;
131 width: 200%;
132 height: 200%;
133 background: linear-gradient(45deg,
134 transparent,
135 rgba(255,255,255,0.1),
136 transparent);
137 transform: rotate(45deg);
138 transition: transform 0.6s ease;
139 }
140
141 .gallery-item:hover::before {
142 transform: translateX(100%) translateY(100%) rotate(45deg);
143 }
144
145 .gallery-item:nth-child(3n) {
146 grid-row: span 2;
147 background: linear-gradient(135deg,
148 rgba(245, 101, 101, 0.8),
149 rgba(247, 149, 51, 0.8));
150 }
151
152 .gallery-item:nth-child(5n) {
153 grid-column: span 2;
154 background: linear-gradient(135deg,
155 rgba(72, 187, 120, 0.8),
156 rgba(56, 178, 172, 0.8));
157 }
158
159 /* Responsive Dashboard Layout */
160 .dashboard-grid {
161 display: grid;
162 grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
163 grid-auto-rows: minmax(150px, auto);
164 gap: 1.5rem;
165 margin: 2rem 0;
166 }
167
168 .dashboard-widget {
169 background: white;
170 border-radius: 16px;
171 padding: 2rem;
172 box-shadow: 0 10px 30px rgba(0,0,0,0.08);
173 display: flex;
174 flex-direction: column;
175 justify-content: space-between;
176 border: 1px solid #e2e8f0;
177 transition: all 0.3s ease;
178 position: relative;
179 overflow: hidden;
180 }
181
182 .dashboard-widget:hover {
183 transform: scale(1.02);
184 box-shadow: 0 15px 40px rgba(0,0,0,0.12);
185 }
186
187 .dashboard-widget--featured {
188 grid-column: span 2;
189 background: linear-gradient(135deg,
190 rgba(102, 126, 234, 0.05),
191 rgba(118, 75, 162, 0.05));
192 border-color: #667eea;
193 }
194
195 .widget-header {
196 display: flex;
197 align-items: center;
198 gap: 1rem;
199 margin-bottom: 1rem;
200 }
201
202 .widget-icon {
203 width: 40px;
204 height: 40px;
205 border-radius: 10px;
206 background: linear-gradient(45deg, #667eea, #764ba2);
207 display: flex;
208 align-items: center;
209 justify-content: center;
210 color: white;
211 font-weight: bold;
212 font-size: 1.2rem;
213 }
214
215 .widget-title {
216 font-size: 1.1rem;
217 font-weight: 600;
218 color: #2c3e50;
219 }
220
221 .widget-value {
222 font-size: 2rem;
223 font-weight: bold;
224 color: #667eea;
225 margin: 1rem 0;
226 }
227
228 .widget-description {
229 color: #64748b;
230 font-size: 0.9rem;
231 }
232
233 /* Responsive Behavior */
234 @media (max-width: 768px) {
235 .container {
236 padding: 1.5rem;
237 }
238
239 .auto-grid {
240 grid-template-columns: 1fr;
241 gap: 1.5rem;
242 }
243
244 .gallery-grid {
245 grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
246 grid-auto-rows: 150px;
247 }
248
249 .gallery-item:nth-child(3n),
250 .gallery-item:nth-child(5n) {
251 grid-column: span 1;
252 grid-row: span 1;
253 }
254
255 .dashboard-widget--featured {
256 grid-column: span 1;
257 }
258 }
259
260 @media (max-width: 480px) {
261 body {
262 padding: 1rem;
263 }
264
265 .section-title {
266 font-size: 1.5rem;
267 }
268
269 .gallery-grid {
270 grid-template-columns: 1fr;
271 }
272 }
273
274 /* Animation for grid items */
275 .card, .gallery-item, .dashboard-widget {
276 animation: fadeInUp 0.6s ease-out forwards;
277 opacity: 0;
278 transform: translateY(30px);
279 }
280
281 .card:nth-child(1) { animation-delay: 0.1s; }
282 .card:nth-child(2) { animation-delay: 0.2s; }
283 .card:nth-child(3) { animation-delay: 0.3s; }
284 .card:nth-child(4) { animation-delay: 0.4s; }
285 .card:nth-child(5) { animation-delay: 0.5s; }
286 .card:nth-child(6) { animation-delay: 0.6s; }
287
288 @keyframes fadeInUp {
289 to {
290 opacity: 1;
291 transform: translateY(0);
292 }
293 }
294 </style>
295</head>
296<body>
297 <div class="container">
298 <section class="section">
299 <h1 class="section-title">🔄 Flexible Grid Systems</h1>
300
301 <!-- Auto-Responsive Card Grid -->
302 <div class="section">
303 <h2 class="section-title">Auto-Responsive Cards</h2>
304 <div class="auto-grid">
305 <div class="card">
306 <h3 class="card-title">📱 Mobile-First</h3>
307 <p class="card-content">Grid automatically adjusts from 1 column on mobile to multiple columns on larger screens. No breakpoints needed!</p>
308 </div>
309 <div class="card">
310 <h3 class="card-title">🎯 Content-Aware</h3>
311 <p class="card-content">Uses minmax(300px, 1fr) to ensure cards never get too small while filling available space efficiently.</p>
312 </div>
313 <div class="card">
314 <h3 class="card-title">⚡ Performance</h3>
315 <p class="card-content">CSS Grid handles responsive behavior natively, reducing JavaScript dependency and improving performance.</p>
316 </div>
317 <div class="card">
318 <h3 class="card-title">🔧 Maintainable</h3>
319 <p class="card-content">Single CSS rule creates fully responsive grid. Easy to modify and extend for different use cases.</p>
320 </div>
321 <div class="card">
322 <h3 class="card-title">🎨 Flexible</h3>
323 <p class="card-content">Works with any content type: cards, images, widgets, or custom components. Adapts to content naturally.</p>
324 </div>
325 <div class="card">
326 <h3 class="card-title">🌟 Modern</h3>
327 <p class="card-content">Leverages latest CSS Grid features like auto-fit, minmax(), and fr units for cutting-edge responsive design.</p>
328 </div>
329 </div>
330 </div>
331
332 <!-- Gallery Grid -->
333 <div class="section">
334 <h2 class="section-title">Dynamic Gallery Grid</h2>
335 <div class="gallery-grid">
336 <div class="gallery-item">Image 1</div>
337 <div class="gallery-item">Image 2</div>
338 <div class="gallery-item">Tall Item</div>
339 <div class="gallery-item">Image 4</div>
340 <div class="gallery-item">Wide Item</div>
341 <div class="gallery-item">Image 6</div>
342 <div class="gallery-item">Image 7</div>
343 <div class="gallery-item">Image 8</div>
344 <div class="gallery-item">Tall Item</div>
345 <div class="gallery-item">Wide Item</div>
346 <div class="gallery-item">Image 11</div>
347 <div class="gallery-item">Image 12</div>
348 </div>
349 </div>
350
351 <!-- Dashboard Grid -->
352 <div class="section">
353 <h2 class="section-title">Responsive Dashboard</h2>
354 <div class="dashboard-grid">
355 <div class="dashboard-widget dashboard-widget--featured">
356 <div class="widget-header">
357 <div class="widget-icon">📊</div>
358 <div class="widget-title">Monthly Revenue</div>
359 </div>
360 <div class="widget-value">$24,500</div>
361 <div class="widget-description">↗️ 12% increase from last month</div>
362 </div>
363 <div class="dashboard-widget">
364 <div class="widget-header">
365 <div class="widget-icon">👥</div>
366 <div class="widget-title">Users</div>
367 </div>
368 <div class="widget-value">1,234</div>
369 <div class="widget-description">Active this month</div>
370 </div>
371 <div class="dashboard-widget">
372 <div class="widget-header">
373 <div class="widget-icon">🎯</div>
374 <div class="widget-title">Conversion</div>
375 </div>
376 <div class="widget-value">3.2%</div>
377 <div class="widget-description">Above target</div>
378 </div>
379 <div class="dashboard-widget">
380 <div class="widget-header">
381 <div class="widget-icon">⚡</div>
382 <div class="widget-title">Performance</div>
383 </div>
384 <div class="widget-value">98%</div>
385 <div class="widget-description">System uptime</div>
386 </div>
387 <div class="dashboard-widget">
388 <div class="widget-header">
389 <div class="widget-icon">💰</div>
390 <div class="widget-title">Profit</div>
391 </div>
392 <div class="widget-value">$8,900</div>
393 <div class="widget-description">This quarter</div>
394 </div>
395 <div class="dashboard-widget">
396 <div class="widget-header">
397 <div class="widget-icon">📈</div>
398 <div class="widget-title">Growth</div>
399 </div>
400 <div class="widget-value">+15%</div>
401 <div class="widget-description">Year over year</div>
402 </div>
403 </div>
404 </div>
405 </section>
406 </div>
407
408 <script>
409 // Add interactive demo functionality
410 document.addEventListener('DOMContentLoaded', function() {
411 // Add resize observer to demonstrate responsive behavior
412 const gridContainers = document.querySelectorAll('.auto-grid, .gallery-grid, .dashboard-grid');
413
414 // Create resize observer
415 if (window.ResizeObserver) {
416 const observer = new ResizeObserver(entries => {
417 entries.forEach(entry => {
418 const width = entry.contentRect.width;
419 const container = entry.target;
420
421 // Add width indicator
422 let indicator = container.querySelector('.width-indicator');
423 if (!indicator) {
424 indicator = document.createElement('div');
425 indicator.className = 'width-indicator';
426 indicator.style.cssText = `
427 position: absolute;
428 top: -25px;
429 right: 0;
430 background: rgba(102, 126, 234, 0.9);
431 color: white;
432 padding: 2px 8px;
433 border-radius: 4px;
434 font-size: 12px;
435 z-index: 10;
436 `;
437 container.style.position = 'relative';
438 container.appendChild(indicator);
439 }
440
441 indicator.textContent = Math.round(width) + 'px';
442 });
443 });
444
445 gridContainers.forEach(container => {
446 observer.observe(container);
447 });
448 }
449
450 // Add click handlers for interactive feedback
451 const cards = document.querySelectorAll('.card, .gallery-item, .dashboard-widget');
452 cards.forEach(card => {
453 card.addEventListener('click', function() {
454 // Create ripple effect
455 const ripple = document.createElement('div');
456 const rect = this.getBoundingClientRect();
457 const size = Math.max(rect.width, rect.height);
458
459 ripple.style.cssText = `
460 position: absolute;
461 border-radius: 50%;
462 background: rgba(255,255,255,0.3);
463 transform: scale(0);
464 animation: ripple 0.6s linear;
465 width: ${size}px;
466 height: ${size}px;
467 left: 50%;
468 top: 50%;
469 margin-left: -${size/2}px;
470 margin-top: -${size/2}px;
471 pointer-events: none;
472 `;
473
474 this.appendChild(ripple);
475
476 setTimeout(() => {
477 ripple.remove();
478 }, 600);
479 });
480 });
481
482 // Add CSS for ripple animation
483 const style = document.createElement('style');
484 style.textContent = `
485 @keyframes ripple {
486 to {
487 transform: scale(2);
488 opacity: 0;
489 }
490 }
491
492 .card, .gallery-item, .dashboard-widget {
493 position: relative;
494 overflow: hidden;
495 cursor: pointer;
496 }
497 `;
498 document.head.appendChild(style);
499 });
500 </script>
501</body>
502</html>This comprehensive example demonstrates several flexible grid patterns:
Auto-Responsive Card Grid:
repeat(auto-fit, minmax(300px, 1fr)) for automatic responsive behaviorDynamic Gallery Grid:
grid-row: span 2 and grid-column: span 2Dashboard Widget Grid:
grid-auto-rows: minmax(150px, auto) for content-aware heightKey Techniques:
The JavaScript adds interactive features and visual feedback to demonstrate grid behavior in real-time.
In the next lesson, we'll explore responsive typography and units, learning how to make text scale beautifully across devices using relative units, viewport units, and fluid typography techniques that complement your flexible grid systems.
Your progress is saved in this browser, on this device only.