⚡ TECH BLOG
Home
Blog
Tags
About
⚡

Powered by Next.js 15 & Modern Web Tech ⚡

Back to Home

CSS Grid and Flexbox Mastery: A Complete Layout Guide

April 15, 2021
cssgridflexboxfrontendlayout
CSS Grid and Flexbox Mastery: A Complete Layout Guide

CSS Grid and Flexbox Mastery: A Complete Layout Guide

CSS Grid and Flexbox are the two most powerful layout tools in modern CSS. Understanding when and how to use each will transform how you build websites. Let's master both.

Flexbox vs Grid: When to Use Which

The key difference is simple:

  • Flexbox is one-dimensional (row OR column)
  • Grid is two-dimensional (rows AND columns)

Use Flexbox When:

  • Layout is one-dimensional
  • Content should determine sizing
  • Aligning items within a container
  • Navigation bars, card content, form layouts

Use Grid When:

  • Layout is two-dimensional
  • You need precise control over placement
  • Building page-level layouts
  • Complex component arrangements

Flexbox Deep Dive

Basic Flexbox Setup

.container {
  display: flex;
  gap: 1rem;
}

/* Direction options */
.container {
  flex-direction: row;        /* default */
  flex-direction: column;
  flex-direction: row-reverse;
  flex-direction: column-reverse;
}

Alignment Properties

.container {
  display: flex;
  
  /* Main axis alignment (horizontal for row) */
  justify-content: flex-start;    /* default */
  justify-content: flex-end;
  justify-content: center;
  justify-content: space-between;
  justify-content: space-around;
  justify-content: space-evenly;
  
  /* Cross axis alignment (vertical for row) */
  align-items: stretch;           /* default */
  align-items: flex-start;
  align-items: flex-end;
  align-items: center;
  align-items: baseline;
  
  /* Wrapping behavior */
  flex-wrap: nowrap;              /* default */
  flex-wrap: wrap;
  flex-wrap: wrap-reverse;
  
  /* Multi-line alignment */
  align-content: flex-start;
  align-content: center;
  align-content: space-between;
}

Flex Item Properties

.item {
  /* Growth factor */
  flex-grow: 0;    /* default */
  flex-grow: 1;    /* grow to fill space */
  
  /* Shrink factor */
  flex-shrink: 1;  /* default */
  flex-shrink: 0;  /* don't shrink */
  
  /* Base size */
  flex-basis: auto;  /* default */
  flex-basis: 200px;
  flex-basis: 25%;
  
  /* Shorthand */
  flex: 0 1 auto;    /* default (grow shrink basis) */
  flex: 1;           /* flex: 1 1 0% */
  flex: auto;        /* flex: 1 1 auto */
  flex: none;        /* flex: 0 0 auto */
  
  /* Individual alignment override */
  align-self: flex-start;
  align-self: center;
  align-self: stretch;
  
  /* Order */
  order: 0;         /* default */
  order: -1;        /* move to start */
  order: 1;         /* move to end */
}

Practical Flexbox Patterns

Centered Content:

.centered {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

Navigation Bar:

.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

.navbar .logo {
  flex-shrink: 0;
}

.navbar .nav-links {
  display: flex;
  gap: 2rem;
}

.navbar .cta-button {
  margin-left: auto;
}

Card Content Layout:

.card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.card-image {
  flex-shrink: 0;
  width: 100%;
}

.card-content {
  flex-grow: 1;
  display: flex;
  flex-direction: column;
}

.card-footer {
  margin-top: auto; /* Pushes footer to bottom */
}

Equal Height Columns:

.columns {
  display: flex;
  gap: 2rem;
}

.column {
  flex: 1;
  /* All columns will have equal height */
}

CSS Grid Deep Dive

Basic Grid Setup

.container {
  display: grid;
  
  /* Define columns */
  grid-template-columns: 200px 200px 200px;
  grid-template-columns: 1fr 2fr 1fr;          /* Fractional units */
  grid-template-columns: repeat(3, 1fr);        /* Repeat function */
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); /* Responsive */
  
  /* Define rows */
  grid-template-rows: 100px auto 100px;
  grid-template-rows: auto 1fr auto;           /* Classic layout pattern */
  
  /* Gap between items */
  gap: 1rem;
  row-gap: 1rem;
  column-gap: 2rem;
}

Grid Template Areas

Grid template areas provide a visual way to define layouts:

.container {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

Grid Placement Properties

.item {
  /* Line-based placement */
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
  
  /* Shorthand */
  grid-column: 1 / 3;
  grid-column: 1 / span 2;
  grid-row: 1 / 2;
  
  /* Area-based placement */
  grid-area: header;
  grid-area: 1 / 1 / 2 / 3; /* row-start / col-start / row-end / col-end */
}

Auto-fill vs Auto-fit

/* auto-fill: Creates empty tracks if needed */
.grid-auto-fill {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  /* Creates as many columns as fit, even if empty */
}

/* auto-fit: Collapses empty tracks */
.grid-auto-fit {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  /* Stretches existing items to fill space */
}

Practical Grid Patterns

Classic Page Layout:

.page {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  min-height: 100vh;
}

/* Responsive */
@media (max-width: 768px) {
  .page {
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "main"
      "sidebar"
      "footer";
  }
}

Image Gallery:

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

.gallery-item.featured {
  grid-column: span 2;
  grid-row: span 2;
}

Dashboard Grid:

.dashboard {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(150px, auto);
  gap: 1.5rem;
}

.widget-small  { grid-column: span 1; }
.widget-medium { grid-column: span 2; }
.widget-large  { grid-column: span 3; }
.widget-full   { grid-column: span 4; }

Masonry-like Layout:

.masonry {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 10px;
  gap: 10px;
}

.masonry-item:nth-child(1) { grid-row: span 20; } /* 200px tall */
.masonry-item:nth-child(2) { grid-row: span 30; } /* 300px tall */
.masonry-item:nth-child(3) { grid-row: span 15; } /* 150px tall */

Combining Grid and Flexbox

The real power comes from using both together:

/* Grid for page structure, Flexbox for component internals */
.page {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

.nav-links {
  display: flex;
  gap: 1.5rem;
}

.main {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  padding: 2rem;
}

.card {
  display: flex;
  flex-direction: column;
}

.card-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: auto;
}

Responsive Patterns

Mobile-First Grid

.responsive-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 640px) {
  .responsive-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .responsive-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1280px) {
  .responsive-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

Intrinsic Responsive Design

/* No media queries needed! */
.intrinsic-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 1.5rem;
}

Holy Grail Layout

.holy-grail {
  display: grid;
  grid-template:
    "header header header" auto
    "nav main aside" 1fr
    "footer footer footer" auto
    / 200px 1fr 200px;
  min-height: 100vh;
}

@media (max-width: 768px) {
  .holy-grail {
    grid-template:
      "header" auto
      "nav" auto
      "main" 1fr
      "aside" auto
      "footer" auto
      / 1fr;
  }
}

Common Pitfalls and Solutions

Flex Item Not Shrinking

/* Problem: Long text overflows */
.flex-item {
  min-width: 0; /* Solution: Allow shrinking */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

Grid Items Not Filling Height

.container {
  display: grid;
  grid-template-rows: 1fr; /* Use fr unit, not auto */
  min-height: 100vh;
}

Gap Property Inconsistencies

/* Use gap shorthand */
.grid {
  display: grid;
  gap: 1rem; /* Works in both Grid and Flexbox */
}

/* Legacy fallback */
.legacy {
  display: grid;
  grid-gap: 1rem; /* Older syntax */
}

Debugging Tips

/* Visualize grid lines */
.debug-grid {
  display: grid;
}

.debug-grid > * {
  outline: 1px solid red;
}

/* Use browser DevTools */
/* Firefox has excellent Grid/Flexbox visualization */

Conclusion

CSS Grid and Flexbox are complementary tools:

  • Use Flexbox for one-dimensional layouts and content alignment
  • Use Grid for two-dimensional layouts and page structure
  • Combine both for optimal results
  • Embrace intrinsic design patterns that reduce media queries

Master these tools and you'll never struggle with CSS layouts again!

Further Resources

  • CSS-Tricks Flexbox Guide
  • CSS-Tricks Grid Guide
  • Grid by Example
  • MDN CSS Grid Layout
Share:

💬 Comments