Table of Contents
- Introduction to CSS Grid
- Grid Container Properties
- Grid Item Properties
- Grid Lines and Tracks
- Grid Areas
- Alignment and Spacing
- Responsive Grid Design
- Advanced Grid Techniques
- Grid vs Flexbox
- Browser Support and Fallbacks
- Practical Examples
- Best Practices
Introduction to CSS Grid
CSS Grid Layout is a two-dimensional layout system for the web. It allows you to create complex, responsive layouts with rows and columns simultaneously. Unlike Flexbox which is primarily one-dimensional, Grid gives you control over both dimensions.
Why CSS Grid?
/* Before Grid - Complex layouts required hacks */ .container { display: flex; flex-wrap: wrap; } .item { width: calc(33.333% - 20px); margin: 10px; /* Still needed clearfix, margin calculations, etc. */ } /* With Grid - Simple and intuitive */ .container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } Basic Grid Example
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Basic Grid Example</title> <style> .grid-container { display: grid; grid-template-columns: 200px 1fr 200px; grid-template-rows: auto 1fr auto; gap: 20px; min-height: 100vh; padding: 20px; background: #f0f0f0; } .header { grid-column: 1 / -1; background: #3498db; color: white; padding: 20px; text-align: center; } .sidebar-left { background: #2ecc71; color: white; padding: 20px; } .main-content { background: #e74c3c; color: white; padding: 20px; } .sidebar-right { background: #f39c12; color: white; padding: 20px; } .footer { grid-column: 1 / -1; background: #9b59b6; color: white; padding: 20px; text-align: center; } </style> </head> <body> <div class="grid-container"> <header class="header">Header</header> <aside class="sidebar-left">Left Sidebar</aside> <main class="main-content">Main Content</main> <aside class="sidebar-right">Right Sidebar</aside> <footer class="footer">Footer</footer> </div> </body> </html> Grid Container Properties
Display and Basic Setup
/* Grid container declaration */ .container { display: grid; /* Block-level grid */ display: inline-grid; /* Inline-level grid */ } /* Creating columns and rows */ .container { display: grid; grid-template-columns: 100px 200px 100px; /* Three columns */ grid-template-rows: 100px 200px; /* Two rows */ gap: 20px; /* Gap between grid items */ } /* Using different units */ .container { display: grid; grid-template-columns: 100px /* Fixed width */ 20% /* Percentage of container */ 1fr /* Fractional unit */ auto /* Auto-sized */ minmax(100px, 1fr) /* Minimum 100px, maximum 1fr */ repeat(3, 1fr); /* Repeat 3 times 1fr */ } Grid Template Columns and Rows
/* Explicit grid definition */ .container { display: grid; /* Columns */ grid-template-columns: 200px 1fr 200px; grid-template-columns: [start] 200px [center] 1fr [end] 200px; /* Named lines */ grid-template-columns: repeat(4, 1fr); /* 4 equal columns */ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Rows */ grid-template-rows: 100px auto 100px; grid-template-rows: [header-start] 100px [content-start] 1fr [footer-start] 100px; /* Gap */ gap: 20px; /* Row and column gap */ row-gap: 20px; /* Only row gap */ column-gap: 20px; /* Only column gap */ } /* Examples of different grid configurations */ .grid-examples { /* Three equal columns */ grid-template-columns: 1fr 1fr 1fr; /* Asymmetric columns */ grid-template-columns: 2fr 1fr 1fr; /* First column twice as wide */ /* Mixed units */ grid-template-columns: 200px 1fr 2fr; /* Fixed, flexible, more flexible */ /* Named grid lines */ grid-template-columns: [left-edge] 1fr [main-start] 3fr [main-end] 1fr [right-edge]; /* Responsive columns */ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); } The fr Unit
/* Understanding the fractional unit */ .container { display: grid; grid-template-columns: 1fr 1fr 1fr; /* Three equal columns */ grid-template-columns: 2fr 1fr 1fr; /* 2:1:1 ratio */ grid-template-columns: 1fr 2fr; /* 1:2 ratio */ } /* fr vs percentage */ .percentage { width: 100%; display: grid; grid-template-columns: 33.33% 33.33% 33.33%; /* Problems with gaps - 33.33% * 3 + gaps > 100% */ } .fr-unit { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px; /* fr automatically accounts for gaps */ } Repeat Function
/* The repeat() function */ .container { display: grid; /* Basic repeat */ grid-template-columns: repeat(4, 1fr); /* 4 equal columns */ grid-template-rows: repeat(3, 100px); /* 3 rows of 100px */ /* Repeat with pattern */ grid-template-columns: repeat(2, 1fr 2fr); /* 1fr, 2fr, 1fr, 2fr */ /* Auto-fill vs Auto-fit */ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } /* Auto-fill vs Auto-fit example */ .auto-fill-demo { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 20px; /* Creates as many columns as possible, keeps empty tracks */ } .auto-fit-demo { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 20px; /* Creates as many columns as possible, collapses empty tracks */ } /* Visual difference */ .auto-fill { /* When fewer items, you'll see empty columns */ } .auto-fit { /* Items expand to fill available space */ } Minmax Function
/* The minmax() function */ .container { display: grid; /* Column with minimum and maximum size */ grid-template-columns: minmax(100px, 1fr) 2fr; /* Minimum 200px, can grow but not shrink below 200px */ grid-template-columns: minmax(200px, 1fr) 1fr; /* Practical examples */ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* Sidebar with min and max */ grid-template-columns: minmax(150px, 250px) 1fr; } /* Complex minmax examples */ .minmax-examples { /* Column that's at least 100px but no more than 300px */ grid-template-columns: minmax(100px, 300px) 1fr; /* Column that's at least 200px but can grow */ grid-template-columns: minmax(200px, auto) 1fr; /* Column that's at most 500px but can shrink */ grid-template-columns: minmax(auto, 500px) 1fr; /* With repeat */ grid-template-columns: repeat(3, minmax(150px, 300px)); } Grid Item Properties
Grid Column and Row Placement
/* Grid item placement */ .item { /* Column placement */ grid-column-start: 1; grid-column-end: 3; /* Shorthand */ grid-column: 1 / 3; /* Row placement */ grid-row-start: 1; grid-row-end: 3; /* Shorthand */ grid-row: 1 / 3; /* Combined shorthand */ grid-area: 1 / 1 / 3 / 3; /* row-start / col-start / row-end / col-end */ } /* Spanning items */ .item { grid-column: span 2; /* Span 2 columns */ grid-row: span 3; /* Span 3 rows */ grid-area: span 2 / span 3; /* Span 2 rows and 3 columns */ } /* Using named lines */ .item { grid-column: main-start / main-end; grid-row: content-start / footer-start; } /* Using named grid areas */ .item { grid-area: header; } Spanning Examples
/* Complete spanning example */ .grid-container { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(3, 100px); gap: 10px; } .item-1 { grid-column: 1 / 3; /* Spans columns 1-2 */ grid-row: 1 / 2; /* Row 1 only */ } .item-2 { grid-column: 3 / -1; /* Spans from column 3 to end */ grid-row: 1 / 2; } .item-3 { grid-column: 1 / 2; grid-row: 2 / 4; /* Spans rows 2-3 */ } .item-4 { grid-column: 2 / 4; grid-row: 2 / 3; } .item-5 { grid-column: 4 / 5; grid-row: 2 / 4; /* Spans rows 2-3 */ } .item-6 { grid-column: 2 / 4; grid-row: 3 / 4; } Grid Area Naming
/* Named grid areas - most intuitive approach */ .container { display: grid; grid-template-areas: "header header header" "sidebar content content" "sidebar footer footer"; grid-template-columns: 1fr 2fr 2fr; grid-template-rows: auto 1fr auto; gap: 20px; } /* Assigning items to named areas */ .header { grid-area: header; } .sidebar { grid-area: sidebar; } .content { grid-area: content; } .footer { grid-area: footer; } /* Complex area patterns */ .container { grid-template-areas: "header header header header" ". main main ." "footer footer footer footer"; } .container { grid-template-areas: "logo nav nav nav" "sidebar content content content" "sidebar footer footer footer"; } /* Empty cells with dots */ .container { grid-template-areas: "header header header header" "sidebar . . widget" "footer footer footer footer"; } Grid Lines and Tracks
Working with Grid Lines
/* Understanding grid lines */ .container { display: grid; grid-template-columns: [col1-start] 1fr [col1-end col2-start] 2fr [col2-end col3-start] 1fr [col3-end]; grid-template-rows: [row1-start] 100px [row1-end row2-start] auto [row2-end]; } /* Using line numbers */ .item { grid-column: 1 / 3; /* Lines 1 to 3 */ grid-row: 1 / -1; /* From first to last line */ } /* Using named lines */ .item { grid-column: col1-start / col2-end; grid-row: row1-start / row2-end; } /* Multiple named lines */ .container { grid-template-columns: [sidebar-start] 200px [sidebar-end main-start] 1fr [main-end]; } .sidebar { grid-column: sidebar-start / sidebar-end; } .main { grid-column: main-start / main-end; } Line-Based Placement Examples
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid Lines Example</title> <style> .grid { display: grid; grid-template-columns: [start] 1fr [content-start] 2fr [content-middle] 1fr [content-end] 1fr [end]; grid-template-rows: [top] 100px [middle] 200px [bottom] 100px [footer-end]; gap: 10px; background: #f0f0f0; padding: 10px; } .item { background: #3498db; color: white; padding: 20px; border-radius: 5px; } .item-1 { grid-column: start / content-middle; grid-row: top / middle; } .item-2 { grid-column: content-middle / content-end; grid-row: top / middle; } .item-3 { grid-column: content-end / end; grid-row: top / bottom; } .item-4 { grid-column: start / content-middle; grid-row: middle / bottom; } .item-5 { grid-column: content-middle / content-end; grid-row: middle / bottom; } .item-6 { grid-column: start / end; grid-row: bottom / footer-end; } </style> </head> <body> <div class="grid"> <div class="item item-1">Item 1</div> <div class="item item-2">Item 2</div> <div class="item item-3">Item 3</div> <div class="item item-4">Item 4</div> <div class="item item-5">Item 5</div> <div class="item item-6">Item 6</div> </div> </body> </html> Grid Areas
Creating Grid Areas
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid Areas Example</title> <style> .grid-container { display: grid; grid-template-areas: "header header header header" "nav main main sidebar" "nav main main ad" "footer footer footer footer"; grid-template-columns: 150px 1fr 2fr 200px; grid-template-rows: 80px 1fr 1fr 60px; gap: 10px; min-height: 100vh; padding: 10px; background: #f5f5f5; } .header { grid-area: header; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; } .nav { grid-area: nav; background: #3498db; color: white; padding: 20px; } .main { grid-area: main; background: #2ecc71; color: white; padding: 20px; } .sidebar { grid-area: sidebar; background: #f39c12; color: white; padding: 20px; } .ad { grid-area: ad; background: #e74c3c; color: white; padding: 20px; } .footer { grid-area: footer; background: #9b59b6; color: white; padding: 20px; } /* Responsive grid areas */ @media (max-width: 768px) { .grid-container { grid-template-areas: "header" "nav" "main" "sidebar" "ad" "footer"; grid-template-columns: 1fr; grid-template-rows: auto; } } </style> </head> <body> <div class="grid-container"> <header class="header">Header</header> <nav class="nav">Navigation</nav> <main class="main">Main Content</main> <aside class="sidebar">Sidebar</aside> <aside class="ad">Advertisement</aside> <footer class="footer">Footer</footer> </div> </body> </html> Complex Grid Area Patterns
/* Magazine-style layout */ .magazine { display: grid; grid-template-areas: "header header header header" "featured featured featured sidebar" "article-1 article-1 article-2 sidebar" "article-3 article-4 article-5 sidebar" "footer footer footer footer"; grid-template-columns: repeat(4, 1fr); gap: 20px; } /* Dashboard layout */ .dashboard { display: grid; grid-template-areas: "header header header header" "stats stats stats stats" "chart1 chart1 chart2 chart2" "chart3 chart3 chart4 chart4" "table table table table" "footer footer footer footer"; grid-template-columns: repeat(4, 1fr); gap: 20px; } /* Holy grail layout */ .holy-grail { display: grid; grid-template-areas: "header header header" "nav main aside" "footer footer footer"; grid-template-columns: 200px 1fr 200px; gap: 20px; } /* Asymmetric layout */ .asymmetric { display: grid; grid-template-areas: "hero hero hero hero" "content content sidebar sidebar" "content content tweet tweet" "cards cards cards cards"; grid-template-columns: repeat(4, 1fr); gap: 20px; } Alignment and Spacing
Aligning Grid Items
/* Grid container alignment properties */ .container { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(3, 100px); gap: 10px; /* Align items within their cells (horizontal) */ justify-items: start; /* start, end, center, stretch (default) */ /* Align items within their cells (vertical) */ align-items: center; /* start, end, center, stretch */ /* Shorthand for both */ place-items: center stretch; /* Align the entire grid within container (horizontal) */ justify-content: center; /* start, end, center, stretch, space-around, space-between, space-evenly */ /* Align the entire grid within container (vertical) */ align-content: center; /* same values as justify-content */ /* Shorthand for both */ place-content: center center; } /* Grid item alignment properties */ .item { /* Override container's justify-items for this item */ justify-self: start; /* start, end, center, stretch */ /* Override container's align-items for this item */ align-self: center; /* start, end, center, stretch */ /* Shorthand for both */ place-self: center stretch; } Alignment Examples
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid Alignment Examples</title> <style> .grid-demo { display: grid; grid-template-columns: repeat(3, 150px); grid-template-rows: repeat(3, 150px); gap: 10px; background: #f0f0f0; padding: 20px; width: 800px; height: 600px; } .item { background: #3498db; color: white; padding: 10px; } /* Different alignment examples */ .demo-1 { justify-items: start; align-items: start; } .demo-2 { justify-items: center; align-items: center; } .demo-3 { justify-items: end; align-items: end; } .demo-4 { justify-items: stretch; align-items: stretch; } .demo-5 { justify-content: center; align-content: center; } .demo-6 { justify-content: space-between; align-content: space-around; } /* Item-level overrides */ .special-item { justify-self: center; align-self: end; background: #e74c3c; } </style> </head> <body> <h2>Justify/Align Items: start</h2> <div class="grid-demo demo-1"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> <h2>Justify/Align Items: center</h2> <div class="grid-demo demo-2"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> <h2>Justify/Align Content: center</h2> <div class="grid-demo demo-5"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> <h2>Item-level Override</h2> <div class="grid-demo demo-1"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item special-item">5</div> <div class="item">6</div> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> </body> </html> Gap and Spacing
/* Grid gap properties */ .container { display: grid; grid-template-columns: repeat(3, 1fr); /* Individual gap properties */ row-gap: 20px; column-gap: 30px; /* Shorthand */ gap: 20px; /* Same for rows and columns */ gap: 20px 30px; /* row-gap column-gap */ } /* Gap examples */ .gap-examples { /* No gaps */ gap: 0; /* Uniform gaps */ gap: 20px; /* Different gaps */ gap: 10px 30px; /* Gaps can be any unit */ gap: 1rem 2%; /* Gaps with minmax */ gap: clamp(10px, 2vw, 30px); } Responsive Grid Design
Media Queries with Grid
/* Responsive grid with media queries */ .container { display: grid; gap: 20px; /* Mobile first approach */ grid-template-columns: 1fr; /* Single column on mobile */ } /* Tablet */ @media (min-width: 768px) { .container { grid-template-columns: repeat(2, 1fr); /* Two columns */ } } /* Desktop */ @media (min-width: 1024px) { .container { grid-template-columns: repeat(3, 1fr); /* Three columns */ } } /* Large desktop */ @media (min-width: 1440px) { .container { grid-template-columns: repeat(4, 1fr); /* Four columns */ } } Auto-Responsive Grids
/* Auto-responsive grid without media queries */ .auto-responsive { display: grid; gap: 20px; /* Automatically adjusts columns based on container width */ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); } /* With minimum width control */ .controlled-responsive { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); } /* Responsive with max-width */ .responsive-container { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); max-width: 1200px; margin: 0 auto; } Responsive Grid Areas
/* Responsive layout with grid areas */ .responsive-layout { display: grid; gap: 20px; grid-template-areas: "header" "nav" "main" "sidebar" "footer"; } @media (min-width: 768px) { .responsive-layout { grid-template-columns: 1fr 3fr; grid-template-areas: "header header" "nav main" "sidebar main" "footer footer"; } } @media (min-width: 1024px) { .responsive-layout { grid-template-columns: 200px 1fr 200px; grid-template-areas: "header header header" "nav main sidebar" "footer footer footer"; } } Complete Responsive Grid Example
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Responsive Grid Example</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', sans-serif; padding: 20px; background: #f5f5f5; } .responsive-grid { display: grid; gap: 20px; max-width: 1400px; margin: 0 auto; } /* Mobile: 1 column */ .responsive-grid { grid-template-columns: 1fr; } /* Tablet: 2 columns */ @media (min-width: 600px) { .responsive-grid { grid-template-columns: repeat(2, 1fr); } } /* Desktop: 4 columns */ @media (min-width: 900px) { .responsive-grid { grid-template-columns: repeat(4, 1fr); } } /* Large desktop: 6 columns with featured items */ @media (min-width: 1200px) { .responsive-grid { grid-template-columns: repeat(6, 1fr); } .featured-card:first-child { grid-column: span 2; grid-row: span 2; } .featured-card:nth-child(2) { grid-column: span 2; } .featured-card:nth-child(3), .featured-card:nth-child(4) { grid-column: span 1; } } .card { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 10px rgba(0,0,0,0.1); transition: transform 0.3s, box-shadow 0.3s; } .card:hover { transform: translateY(-5px); box-shadow: 0 5px 20px rgba(0,0,0,0.15); } .card-image { width: 100%; height: 200px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; color: white; font-size: 2rem; } .card-content { padding: 20px; } .card-title { font-size: 1.2rem; margin-bottom: 10px; color: #333; } .card-description { color: #666; line-height: 1.5; margin-bottom: 15px; } .card-meta { display: flex; justify-content: space-between; color: #999; font-size: 0.9rem; padding-top: 10px; border-top: 1px solid #eee; } .featured-card .card-image { height: 250px; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); } .featured-card .card-title { font-size: 1.5rem; } </style> </head> <body> <div class="responsive-grid"> <!-- Featured cards --> <div class="card featured-card"> <div class="card-image">📸</div> <div class="card-content"> <h3 class="card-title">Featured Project</h3> <p class="card-description">This is our main featured project with detailed description and special styling.</p> <div class="card-meta"> <span>👁️ 2.5k views</span> <span>❤️ 1.2k likes</span> </div> </div> </div> <div class="card featured-card"> <div class="card-image">🎨</div> <div class="card-content"> <h3 class="card-title">Design System</h3> <p class="card-description">Complete design system with components and guidelines.</p> <div class="card-meta"> <span>👁️ 1.8k views</span> <span>❤️ 890 likes</span> </div> </div> </div> <!-- Regular cards --> <div class="card"> <div class="card-image">💻</div> <div class="card-content"> <h3 class="card-title">Web Development</h3> <p class="card-description">Modern web development techniques and best practices.</p> <div class="card-meta"> <span>👁️ 1.2k views</span> <span>❤️ 450 likes</span> </div> </div> </div> <div class="card"> <div class="card-image">📱</div> <div class="card-content"> <h3 class="card-title">Mobile Apps</h3> <p class="card-description">Cross-platform mobile development with React Native.</p> <div class="card-meta"> <span>👁️ 980 views</span> <span>❤️ 320 likes</span> </div> </div> </div> <div class="card"> <div class="card-image">☁️</div> <div class="card-content"> <h3 class="card-title">Cloud Computing</h3> <p class="card-description">AWS, Azure, and Google Cloud platform tutorials.</p> <div class="card-meta"> <span>👁️ 1.5k views</span> <span>❤️ 670 likes</span> </div> </div> </div> <div class="card"> <div class="card-image">🤖</div> <div class="card-content"> <h3 class="card-title">Machine Learning</h3> <p class="card-description">Introduction to machine learning with Python.</p> <div class="card-meta"> <span>👁️ 2.1k views</span> <span>❤️ 1.1k likes</span> </div> </div> </div> <div class="card"> <div class="card-image">🔒</div> <div class="card-content"> <h3 class="card-title">Cybersecurity</h3> <p class="card-description">Essential security practices for developers.</p> <div class="card-meta"> <span>👁️ 750 views</span> <span>❤️ 280 likes</span> </div> </div> </div> <div class="card"> <div class="card-image">🚀</div> <div class="card-content"> <h3 class="card-title">DevOps</h3> <p class="card-description">CI/CD pipelines and infrastructure as code.</p> <div class="card-meta"> <span>👁️ 890 views</span> <span>❤️ 340 likes</span> </div> </div> </div> <div class="card"> <div class="card-image">🎮</div> <div class="card-content"> <h3 class="card-title">Game Development</h3> <p class="card-description">Create games with Unity and Unreal Engine.</p> <div class="card-meta"> <span>👁️ 1.1k views</span> <span>❤️ 560 likes</span> </div> </div> </div> <div class="card"> <div class="card-image">📊</div> <div class="card-content"> <h3 class="card-title">Data Science</h3> <p class="card-description">Data analysis and visualization techniques.</p> <div class="card-meta"> <span>👁️ 670 views</span> <span>❤️ 230 likes</span> </div> </div> </div> </div> </body> </html> Advanced Grid Techniques
Nested Grids
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Nested Grids Example</title> <style> .outer-grid { display: grid; grid-template-columns: 1fr 2fr; gap: 20px; background: #f0f0f0; padding: 20px; } .outer-item { background: white; padding: 20px; border-radius: 8px; } .inner-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; } .inner-item { background: #3498db; color: white; padding: 15px; border-radius: 5px; text-align: center; } .complex-inner { display: grid; grid-template-areas: "header header" "sidebar content" "footer footer"; grid-template-columns: 100px 1fr; gap: 10px; background: #2ecc71; padding: 10px; border-radius: 5px; } .complex-header { grid-area: header; } .complex-sidebar { grid-area: sidebar; } .complex-content { grid-area: content; } .complex-footer { grid-area: footer; } .complex-item { background: rgba(255,255,255,0.2); color: white; padding: 10px; border-radius: 3px; } </style> </head> <body> <div class="outer-grid"> <div class="outer-item"> <h3>Simple Nested Grid</h3> <div class="inner-grid"> <div class="inner-item">Item 1</div> <div class="inner-item">Item 2</div> <div class="inner-item">Item 3</div> <div class="inner-item">Item 4</div> </div> </div> <div class="outer-item"> <h3>Complex Nested Grid</h3> <div class="complex-inner"> <div class="complex-item complex-header">Header</div> <div class="complex-item complex-sidebar">Sidebar</div> <div class="complex-item complex-content">Content</div> <div class="complex-item complex-footer">Footer</div> </div> </div> </div> </body> </html> Subgrid (Level 2 Feature)
/* Subgrid - currently supported in Firefox and Safari */ .parent-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; } .child-grid { display: grid; grid-column: span 2; grid-template-columns: subgrid; /* Inherit parent's columns */ gap: inherit; /* Inherit parent's gap */ } /* Subgrid example */ .subgrid-example { display: grid; grid-template-columns: 200px 1fr 200px; gap: 20px; } .nested-with-subgrid { display: grid; grid-column: 2 / 3; grid-template-columns: subgrid; grid-template-rows: subgrid; } Masonry Layout with Grid
/* Masonry-like layout with grid */ .masonry { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; } .masonry-item { break-inside: avoid; } /* Grid with varying row heights */ .varying-heights { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); grid-auto-rows: minmax(100px, auto); gap: 20px; } .varying-heights-item:nth-child(3n+1) { grid-row: span 2; /* Tall items */ } .varying-heights-item:nth-child(3n+2) { grid-row: span 3; /* Even taller items */ } Grid Ordering
/* Reordering grid items */ .container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } /* Order can be changed using grid placement */ .item-1 { grid-column: 3; } /* Move to column 3 */ .item-2 { grid-column: 1; } /* Move to column 1 */ .item-3 { grid-column: 2; } /* Move to column 2 */ /* Order with media queries */ @media (max-width: 768px) { .item-1 { grid-column: 1; } .item-2 { grid-column: 2; } .item-3 { grid-column: 3; } } /* Visual reordering example */ .reorder-demo { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; } .reorder-demo .item:nth-child(1) { order: 3; } .reorder-demo .item:nth-child(2) { order: 1; } .reorder-demo .item:nth-child(3) { order: 2; } Implicit vs Explicit Grid
/* Explicit grid - defined with template */ .explicit { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: 100px 200px; /* Only first 2 rows are explicitly defined */ } /* Implicit grid - auto-generated rows/columns */ .implicit { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 150px; /* Size of auto-generated rows */ grid-auto-columns: 200px; /* Size of auto-generated columns */ grid-auto-flow: row; /* Auto-placement algorithm */ } /* Grid auto-flow examples */ .auto-flow-row { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-flow: row; /* Fill rows first (default) */ grid-auto-rows: 100px; } .auto-flow-column { display: grid; grid-template-rows: repeat(3, 100px); grid-auto-flow: column; /* Fill columns first */ grid-auto-columns: 200px; } .auto-flow-dense { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-flow: row dense; /* Dense packing algorithm */ grid-auto-rows: 100px; } Grid vs Flexbox
When to Use Grid vs Flexbox
/* Grid: Two-dimensional layout */ .grid-2d { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, auto); gap: 20px; } /* Flexbox: One-dimensional layout */ .flex-1d { display: flex; flex-wrap: wrap; gap: 20px; } .flex-1d > * { flex: 1 1 200px; /* Items wrap when needed */ } Comparison Examples
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid vs Flexbox</title> <style> .comparison { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; max-width: 1200px; margin: 0 auto; padding: 20px; } /* Grid layout */ .grid-layout { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; background: #f0f0f0; padding: 20px; border-radius: 10px; } /* Flexbox layout */ .flex-layout { display: flex; flex-wrap: wrap; gap: 15px; background: #f0f0f0; padding: 20px; border-radius: 10px; } .flex-layout > * { flex: 1 1 calc(33.333% - 15px); min-width: 200px; } .item { background: #3498db; color: white; padding: 20px; text-align: center; border-radius: 5px; } /* Complex grid layout */ .complex-grid { display: grid; grid-template-areas: "header header header" "sidebar main main" "footer footer footer"; grid-template-columns: 200px 1fr 1fr; gap: 15px; background: #f0f0f0; padding: 20px; border-radius: 10px; } /* Complex flexbox (less suitable) */ .complex-flex { display: flex; flex-wrap: wrap; background: #f0f0f0; padding: 20px; border-radius: 10px; } .complex-flex > * { margin: 7.5px; } .complex-flex .header { flex: 0 0 calc(100% - 15px); } .complex-flex .sidebar { flex: 0 0 200px; } .complex-flex .main { flex: 1 1 calc(100% - 200px - 30px); } .complex-flex .footer { flex: 0 0 calc(100% - 15px); } </style> </head> <body> <h2>Grid vs Flexbox Comparison</h2> <div class="comparison"> <div> <h3>CSS Grid</h3> <p>Best for 2D layouts (rows and columns)</p> <div class="grid-layout"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> </div> <div> <h3>Flexbox</h3> <p>Best for 1D layouts (rows OR columns)</p> <div class="flex-layout"> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> </div> </div> <h2>Complex Layout Comparison</h2> <div class="comparison"> <div> <h3>Grid - Natural</h3> <div class="complex-grid"> <div class="item" style="grid-area: header;">Header</div> <div class="item" style="grid-area: sidebar;">Sidebar</div> <div class="item" style="grid-area: main;">Main Content</div> <div class="item" style="grid-area: footer;">Footer</div> </div> </div> <div> <h3>Flexbox - Forced</h3> <div class="complex-flex"> <div class="item header">Header</div> <div class="item sidebar">Sidebar</div> <div class="item main">Main Content</div> <div class="item footer">Footer</div> </div> </div> </div> </body> </html> Decision Guide
/* Use Grid when: */ .grid-usage { /* 1. You need both row and column control */ display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, auto); /* 2. You have complex alignments */ justify-items: center; align-items: center; /* 3. You need gaps between items */ gap: 20px; /* 4. You want to overlap items */ position: relative; } /* Use Flexbox when: */ .flex-usage { /* 1. You need a one-dimensional layout */ display: flex; /* 2. You want content to dictate size */ flex: 1 1 auto; /* 3. You need dynamic reordering */ order: 1; /* 4. You want items to wrap */ flex-wrap: wrap; } Browser Support and Fallbacks
Feature Detection with @supports
/* Modern browsers with Grid support */ @supports (display: grid) { .container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; } } /* Fallback for older browsers */ @supports not (display: grid) { .container { display: flex; flex-wrap: wrap; } .container > * { width: calc(33.333% - 20px); margin: 10px; } } Complete Fallback Example
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Grid with Fallbacks</title> <style> /* Base styles (for all browsers) */ .grid-fallback { display: flex; flex-wrap: wrap; margin: -10px; } .grid-fallback > * { width: calc(33.333% - 20px); margin: 10px; background: #3498db; color: white; padding: 20px; box-sizing: border-box; } /* Grid for modern browsers */ @supports (display: grid) { .grid-fallback { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin: 0; } .grid-fallback > * { width: auto; margin: 0; } /* Advanced grid features */ .grid-fallback.featured { grid-template-columns: 2fr 1fr 1fr; } .grid-fallback .wide { grid-column: span 2; } } </style> </head> <body> <div class="grid-fallback featured"> <div class="wide">Wide Item</div> <div>Item 2</div> <div>Item 3</div> <div>Item 4</div> <div>Item 5</div> <div>Item 6</div> </div> </body> </html> Browser Support Table
/* Browser support for CSS Grid */ /* Chrome: 57+ (2017) Firefox: 52+ (2017) Safari: 10.1+ (2017) Edge: 16+ (2017) IE: No support (use -ms- prefix for older Edge) */ /* IE/Edge legacy syntax */ .grid-ie { display: -ms-grid; -ms-grid-columns: 1fr 20px 1fr 20px 1fr; -ms-grid-rows: auto 20px auto; } .item-ie { -ms-grid-column: 1; -ms-grid-row: 1; } Practical Examples
Example 1: Magazine Layout
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Magazine Layout</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Georgia', serif; background: #f5f5f5; padding: 20px; } .magazine { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; max-width: 1400px; margin: 0 auto; } .header { grid-column: 1 / -1; text-align: center; padding: 40px; background: white; border-bottom: 3px solid #333; margin-bottom: 20px; } .header h1 { font-size: 3rem; letter-spacing: 2px; } .featured-article { grid-column: span 2; grid-row: span 2; background: white; padding: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .featured-article img { width: 100%; height: 300px; object-fit: cover; margin-bottom: 15px; } .featured-article h2 { font-size: 2rem; margin-bottom: 10px; } .featured-article .meta { color: #666; margin-bottom: 15px; font-style: italic; } .article-card { background: white; padding: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .article-card.small { grid-column: span 1; } .article-card.medium { grid-column: span 2; } .article-card img { width: 100%; height: 150px; object-fit: cover; margin-bottom: 10px; } .article-card h3 { font-size: 1.3rem; margin-bottom: 8px; } .sidebar { grid-column: span 1; grid-row: span 3; background: #f0f0f0; padding: 20px; } .sidebar h3 { border-bottom: 2px solid #333; padding-bottom: 10px; margin-bottom: 15px; } .sidebar ul { list-style: none; } .sidebar li { margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #ddd; } .sidebar a { color: #333; text-decoration: none; } .sidebar a:hover { color: #666; } .advertisement { grid-column: span 1; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; display: flex; align-items: center; justify-content: center; } .footer { grid-column: 1 / -1; text-align: center; padding: 30px; background: #333; color: white; margin-top: 20px; } @media (max-width: 900px) { .magazine { grid-template-columns: repeat(2, 1fr); } .featured-article { grid-column: span 2; } .sidebar { grid-column: span 2; grid-row: auto; } } @media (max-width: 600px) { .magazine { grid-template-columns: 1fr; } .featured-article, .article-card, .sidebar, .advertisement { grid-column: 1 !important; } } </style> </head> <body> <div class="magazine"> <header class="header"> <h1>The Daily Chronicle</h1> <p>Your source for news and insights</p> </header> <article class="featured-article"> <img src="https://via.placeholder.com/800x400" alt="Featured"> <h2>Breaking News: Major Discovery in Science</h2> <div class="meta">By Jane Smith | 2 hours ago</div> <p>Scientists have made a groundbreaking discovery that could change our understanding of the universe. This remarkable finding opens up new possibilities for research and development across multiple fields...</p> </article> <article class="article-card"> <img src="https://via.placeholder.com/300x150" alt="Article"> <h3>Technology Trends 2024</h3> <p>The latest innovations shaping our digital future...</p> </article> <article class="article-card"> <img src="https://via.placeholder.com/300x150" alt="Article"> <h3>Health & Wellness</h3> <p>New studies reveal surprising benefits of meditation...</p> </article> <aside class="sidebar"> <h3>Popular Articles</h3> <ul> <li><a href="#">Understanding Climate Change</a></li> <li><a href="#">Guide to Remote Work</a></li> <li><a href="#">Investment Strategies</a></li> <li><a href="#">Travel Destinations 2024</a></li> <li><a href="#">Recipe of the Week</a></li> </ul> <h3 style="margin-top: 30px;">Categories</h3> <ul> <li><a href="#">Technology</a></li> <li><a href="#">Science</a></li> <li><a href="#">Health</a></li> <li><a href="#">Business</a></li> <li><a href="#">Entertainment</a></li> </ul> </aside> <article class="article-card"> <img src="https://via.placeholder.com/300x150" alt="Article"> <h3>Space Exploration</h3> <p>New missions planned for Mars colonization...</p> </article> <div class="advertisement"> <div> <h3>Advertisement</h3> <p>Your ad could be here!</p> </div> </div> <article class="article-card medium"> <img src="https://via.placeholder.com/600x200" alt="Article"> <h3>Economic Outlook</h3> <p>Experts predict steady growth for the coming year with new opportunities in emerging markets...</p> </article> <article class="article-card"> <img src="https://via.placeholder.com/300x150" alt="Article"> <h3>Sports Update</h3> <p>Local team advances to championship...</p> </article> <footer class="footer"> <p>© 2024 The Daily Chronicle. All rights reserved.</p> </footer> </div> </body> </html> Example 2: Dashboard Layout
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Dashboard Layout</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a2e; color: white; } .dashboard { display: grid; grid-template-columns: 250px 1fr 1fr 1fr; grid-template-rows: auto 1fr auto; grid-template-areas: "sidebar header header header" "sidebar stats charts activity" "sidebar recent recent recent"; min-height: 100vh; gap: 20px; padding: 20px; } .sidebar { grid-area: sidebar; background: #16213e; padding: 20px; border-radius: 10px; } .logo { font-size: 1.5rem; font-weight: bold; padding: 20px 0; border-bottom: 1px solid #0f3460; margin-bottom: 30px; } .nav-item { padding: 12px 15px; margin: 5px 0; border-radius: 8px; cursor: pointer; transition: background 0.3s; } .nav-item:hover { background: #0f3460; } .nav-item.active { background: #0f3460; border-left: 3px solid #e94560; } .header { grid-area: header; background: #16213e; padding: 20px; border-radius: 10px; display: flex; justify-content: space-between; align-items: center; } .search-bar { display: flex; align-items: center; background: #0f3460; padding: 8px 15px; border-radius: 20px; width: 300px; } .search-bar input { background: transparent; border: none; color: white; margin-left: 10px; width: 100%; outline: none; } .user-profile { display: flex; align-items: center; gap: 15px; } .avatar { width: 40px; height: 40px; background: #e94560; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; } .stats { grid-area: stats; display: grid; grid-template-columns: 1fr; gap: 15px; } .stat-card { background: #16213e; padding: 20px; border-radius: 10px; display: flex; flex-direction: column; } .stat-title { color: #888; font-size: 0.9rem; margin-bottom: 10px; } .stat-value { font-size: 2rem; font-weight: bold; margin-bottom: 5px; } .stat-change { color: #4caf50; font-size: 0.9rem; } .charts { grid-area: charts; background: #16213e; padding: 20px; border-radius: 10px; } .chart-placeholder { height: 200px; background: #0f3460; border-radius: 8px; margin-top: 15px; display: flex; align-items: flex-end; padding: 10px; } .bar { flex: 1; background: linear-gradient(to top, #e94560, #ff6b6b); margin: 0 5px; border-radius: 5px 5px 0 0; transition: height 0.3s; } .activity { grid-area: activity; background: #16213e; padding: 20px; border-radius: 10px; } .activity-item { display: flex; align-items: center; gap: 15px; padding: 12px 0; border-bottom: 1px solid #0f3460; } .activity-icon { width: 35px; height: 35px; background: #0f3460; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .activity-content { flex: 1; } .activity-time { color: #888; font-size: 0.8rem; } .recent { grid-area: recent; background: #16213e; padding: 20px; border-radius: 10px; } .recent-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .recent-table { width: 100%; } .recent-table th { text-align: left; padding: 10px; color: #888; font-weight: normal; border-bottom: 1px solid #0f3460; } .recent-table td { padding: 10px; border-bottom: 1px solid #0f3460; } .badge { background: #0f3460; padding: 3px 8px; border-radius: 12px; font-size: 0.8rem; } .badge.success { background: #4caf50; } .badge.warning { background: #ff9800; } .badge.danger { background: #e94560; } @media (max-width: 1024px) { .dashboard { grid-template-areas: "sidebar header header" "sidebar stats stats" "sidebar charts activity" "sidebar recent recent"; grid-template-columns: 200px 1fr 1fr; } } @media (max-width: 768px) { .dashboard { grid-template-areas: "header" "stats" "charts" "activity" "recent" "sidebar"; grid-template-columns: 1fr; } .sidebar { display: none; /* Would need mobile menu */ } } </style> </head> <body> <div class="dashboard"> <aside class="sidebar"> <div class="logo">📊 Dashboard</div> <nav> <div class="nav-item active">🏠 Overview</div> <div class="nav-item">📈 Analytics</div> <div class="nav-item">👥 Users</div> <div class="nav-item">📦 Products</div> <div class="nav-item">💰 Sales</div> <div class="nav-item">⚙️ Settings</div> </nav> </aside> <header class="header"> <div class="search-bar"> <span>🔍</span> <input type="text" placeholder="Search..."> </div> <div class="user-profile"> <span>🔔</span> <span>📧</span> <div class="avatar">JD</div> </div> </header> <div class="stats"> <div class="stat-card"> <div class="stat-title">Total Revenue</div> <div class="stat-value">$124,563</div> <div class="stat-change">↑ 12.5% from last month</div> </div> <div class="stat-card"> <div class="stat-title">Active Users</div> <div class="stat-value">2,345</div> <div class="stat-change">↑ 8.2% from last month</div> </div> <div class="stat-card"> <div class="stat-title">New Orders</div> <div class="stat-value">567</div> <div class="stat-change">↓ 3.1% from last month</div> </div> </div> <div class="charts"> <h3>Revenue Overview</h3> <div class="chart-placeholder"> <div class="bar" style="height: 60%;"></div> <div class="bar" style="height: 75%;"></div> <div class="bar" style="height: 55%;"></div> <div class="bar" style="height: 80%;"></div> <div class="bar" style="height: 70%;"></div> <div class="bar" style="height: 90%;"></div> <div class="bar" style="height: 65%;"></div> </div> </div> <div class="activity"> <h3>Recent Activity</h3> <div class="activity-item"> <div class="activity-icon">👤</div> <div class="activity-content"> <div>New user registered</div> <div class="activity-time">5 minutes ago</div> </div> </div> <div class="activity-item"> <div class="activity-icon">💰</div> <div class="activity-content"> <div>New order #12345</div> <div class="activity-time">15 minutes ago</div> </div> </div> <div class="activity-item"> <div class="activity-icon">⭐</div> <div class="activity-content"> <div>New review received</div> <div class="activity-time">32 minutes ago</div> </div> </div> <div class="activity-item"> <div class="activity-icon">📧</div> <div class="activity-content"> <div>Support ticket opened</div> <div class="activity-time">1 hour ago</div> </div> </div> </div> <div class="recent"> <div class="recent-header"> <h3>Recent Orders</h3> <a href="#" style="color: #e94560;">View All →</a> </div> <table class="recent-table"> <thead> <tr> <th>Order ID</th> <th>Customer</th> <th>Product</th> <th>Status</th> <th>Amount</th> </tr> </thead> <tbody> <tr> <td>#12345</td> <td>John Doe</td> <td>Product A</td> <td><span class="badge success">Completed</span></td> <td>$129.99</td> </tr> <tr> <td>#12346</td> <td>Jane Smith</td> <td>Product B</td> <td><span class="badge warning">Pending</span></td> <td>$89.99</td> </tr> <tr> <td>#12347</td> <td>Bob Johnson</td> <td>Product C</td> <td><span class="badge danger">Cancelled</span></td> <td>$199.99</td> </tr> <tr> <td>#12348</td> <td>Alice Brown</td> <td>Product A</td> <td><span class="badge success">Completed</span></td> <td>$129.99</td> </tr> </tbody> </table> </div> </div> </body> </html> Example 3: Product Grid
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Product Grid</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; padding: 20px; } .product-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 25px; max-width: 1400px; margin: 0 auto; } .product-card { background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 3px 10px rgba(0,0,0,0.1); transition: transform 0.3s, box-shadow 0.3s; display: grid; grid-template-rows: 200px 1fr auto; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 5px 20px rgba(0,0,0,0.15); } .product-image { width: 100%; height: 200px; object-fit: cover; } .product-info { padding: 20px; } .product-title { font-size: 1.2rem; margin-bottom: 10px; color: #333; } .product-description { color: #666; line-height: 1.5; margin-bottom: 15px; font-size: 0.95rem; } .product-meta { display: grid; grid-template-columns: 1fr auto; align-items: center; padding: 15px 20px; background: #f9f9f9; border-top: 1px solid #eee; } .product-price { font-size: 1.3rem; font-weight: bold; color: #2c3e50; } .product-rating { color: #f39c12; } .product-actions { padding: 15px 20px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } .btn { padding: 10px; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; transition: background 0.3s; } .btn-primary { background: #3498db; color: white; } .btn-primary:hover { background: #2980b9; } .btn-secondary { background: #ecf0f1; color: #34495e; } .btn-secondary:hover { background: #bdc3c7; } .badge { position: absolute; top: 10px; left: 10px; background: #e74c3c; color: white; padding: 5px 10px; border-radius: 20px; font-size: 0.8rem; font-weight: bold; } .product-card { position: relative; } /* Featured product styles */ .product-card.featured { grid-column: span 2; grid-row: span 2; display: grid; grid-template-rows: 300px 1fr auto; } .product-card.featured .product-image { height: 300px; } .product-card.featured .product-title { font-size: 1.5rem; } /* Responsive adjustments */ @media (max-width: 768px) { .product-grid { gap: 15px; } .product-card.featured { grid-column: span 1; grid-row: span 1; grid-template-rows: 200px 1fr auto; } .product-card.featured .product-image { height: 200px; } } </style> </head> <body> <div class="product-grid"> <!-- Featured Product --> <div class="product-card featured"> <span class="badge">Featured</span> <img src="https://via.placeholder.com/600x400" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">Premium Wireless Headphones</h3> <p class="product-description">Experience crystal-clear sound with our premium wireless headphones. Features active noise cancellation, 30-hour battery life, and comfortable ergonomic design.</p> </div> <div class="product-meta"> <span class="product-price">$299.99</span> <span class="product-rating">★★★★★ (245)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <!-- Regular Products --> <div class="product-card"> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">Smart Watch</h3> <p class="product-description">Track your fitness, receive notifications, and more with this sleek smartwatch.</p> </div> <div class="product-meta"> <span class="product-price">$199.99</span> <span class="product-rating">★★★★☆ (156)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <div class="product-card"> <span class="badge" style="background: #f39c12;">Sale</span> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">Bluetooth Speaker</h3> <p class="product-description">Portable waterproof speaker with amazing sound quality and 20-hour battery life.</p> </div> <div class="product-meta"> <span class="product-price" style="color: #e74c3c;">$79.99</span> <span class="product-rating">★★★★☆ (89)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <div class="product-card"> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">Tablet Pro</h3> <p class="product-description">10.5-inch display, 128GB storage, perfect for work and entertainment.</p> </div> <div class="product-meta"> <span class="product-price">$449.99</span> <span class="product-rating">★★★★☆ (312)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <div class="product-card"> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">Gaming Mouse</h3> <p class="product-description">RGB gaming mouse with programmable buttons and precise optical sensor.</p> </div> <div class="product-meta"> <span class="product-price">$59.99</span> <span class="product-rating">★★★☆☆ (42)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <div class="product-card"> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">Mechanical Keyboard</h3> <p class="product-description">Tactile mechanical switches with RGB backlighting and wrist rest.</p> </div> <div class="product-meta"> <span class="product-price">$129.99</span> <span class="product-rating">★★★★★ (178)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <div class="product-card"> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">USB-C Hub</h3> <p class="product-description">7-in-1 USB-C hub with HDMI, USB ports, and card reader.</p> </div> <div class="product-meta"> <span class="product-price">$49.99</span> <span class="product-rating">★★★★☆ (67)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> <div class="product-card"> <img src="https://via.placeholder.com/400x300" alt="Product" class="product-image"> <div class="product-info"> <h3 class="product-title">External SSD</h3> <p class="product-description">500GB portable SSD with USB 3.2 Gen 2 for lightning-fast transfers.</p> </div> <div class="product-meta"> <span class="product-price">$89.99</span> <span class="product-rating">★★★★☆ (94)</span> </div> <div class="product-actions"> <button class="btn btn-primary">Add to Cart</button> <button class="btn btn-secondary">Quick View</button> </div> </div> </div> </body> </html> Best Practices
Grid Architecture Best Practices
/* 1. Use meaningful grid area names */ .container { display: grid; grid-template-areas: "header header" "sidebar main" "footer footer"; } /* 2. Keep it simple - don't overcomplicate */ .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* Simple, responsive, maintainable */ } /* 3. Use fractions (fr) over percentages */ .container { grid-template-columns: 1fr 2fr 1fr; /* Good */ grid-template-columns: 25% 50% 25%; /* May cause issues with gaps */ } /* 4. Plan for responsiveness */ .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; } /* 5. Use gap for consistent spacing */ .container { gap: 20px; /* Consistent spacing */ } /* 6. Avoid over-specificity */ /* Bad */ body .main .content .grid .item { } /* Good */ .grid .item { } /* 7. Document complex layouts */ /** * Dashboard layout * Header: full width * Sidebar: 250px fixed * Main: flexible content * Footer: full width */ .dashboard { display: grid; grid-template-columns: 250px 1fr; grid-template-areas: "header header" "sidebar main" "footer footer"; } Performance Considerations
/* 1. Limit grid complexity */ .container { display: grid; grid-template-columns: repeat(4, 1fr); /* 4 tracks */ /* Avoid dozens of tracks */ } /* 2. Use minmax for responsive designs */ .container { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } /* 3. Avoid grid reflow in animations */ .animate { will-change: transform; /* Better performance */ transform: translateZ(0); } /* 4. Use contain for isolation */ .isolated { contain: layout; /* Creates new formatting context */ } Grid Checklist
/* Grid implementation checklist */ .container { /* ✅ Define grid container */ display: grid; /* ✅ Set up columns */ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); /* ✅ Add consistent gaps */ gap: 20px; /* ✅ Consider responsive behavior */ /* Already handled by auto-fit */ /* ✅ Test on different screen sizes */ /* Use media queries if needed */ /* ✅ Add fallbacks if needed */ @supports not (display: grid) { /* Fallback styles */ } } Conclusion
CSS Grid Layout is a powerful tool for creating complex, responsive layouts:
Key Takeaways
- Two-dimensional control: Grid handles both rows and columns simultaneously
- Simple syntax: Create complex layouts with minimal code
- Responsive by design: Auto-fit, minmax, and repeat make grids naturally responsive
- Alignment control: Fine-tune item placement with alignment properties
- Grid areas: Name and place items intuitively
- No layout hacks: Eliminate need for floats, clearfix, and complex calculations
When to Use Grid
✅ Full page layouts
✅ Dashboard designs
✅ Card grids
✅ Magazine layouts
✅ Complex forms
✅ Image galleries
When to Use Other Tools
❌ Simple navigation bars → Flexbox
❌ One-dimensional lists → Flexbox
❌ Text content → Normal flow
❌ Small components → Flexbox or normal flow
Next Steps
- Practice creating different grid layouts
- Combine Grid with Flexbox for optimal results
- Experiment with nested grids
- Test on different browsers and devices
- Explore subgrid for advanced patterns
CSS Grid has revolutionized web layout design. Master it, and you'll be able to create virtually any layout you can imagine!