← Back to Learning Path SCSS • Level 3 • Lesson 7 of 9
Level 3 progress 0% complete

Lesson 7: Advanced Grid Patterns

Master complex layout patterns with SCSS: masonry, dashboard layouts, and more.

Beyond Basic Grids

You have mastered the fundamentals. Now let's tackle advanced patterns that solve real-world layout challenges. We will use SCSS to make these complex layouts maintainable and reusable.

Level Up These patterns appear in production apps daily. Learning to build them with SCSS will make you a valuable team member on any web project.

Pattern 1: Masonry Grid

The Pinterest-style masonry layout where items have different heights:

// Masonry configuration
$masonry-columns: 4;
$masonry-gap: 16px;

@mixin masonry-grid($cols: $masonry-columns, $gap: $masonry-gap) {
  display: grid;
  grid-template-columns: repeat($cols, 1fr);
  grid-auto-rows: 10px; // Small row height for granular control
  gap: $gap;
  
  // Make items span the rows they need
  > * {
    // Calculate how many rows based on content height
    // This would be set per item or via JavaScript
  }
}

// Responsive masonry
.masonry {
  @include masonry-grid(2, 12px);
  
  @media (min-width: 768px) {
    @include masonry-grid(3, 16px);
  }
  
  @media (min-width: 1024px) {
    @include masonry-grid(4, 20px);
  }
}

// Item spanning mixin
@mixin masonry-item($row-span) {
  grid-row: span $row-span;
}

Pattern 2: Dashboard Layout

Complex dashboard with repositionable widgets:

// Dashboard grid system
$dashboard-cols: 12;
$dashboard-rows: 12;
$dashboard-gap: 16px;

@mixin dashboard-container {
  display: grid;
  grid-template-columns: repeat($dashboard-cols, 1fr);
  grid-template-rows: repeat($dashboard-rows, minmax(80px, auto));
  gap: $dashboard-gap;
  padding: $dashboard-gap;
  min-height: 100vh;
}

// Widget positioning mixin
@mixin widget($col-start, $col-span, $row-start, $row-span) {
  grid-column: $col-start / span $col-span;
  grid-row: $row-start / span $row-span;
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

// Usage
.dashboard {
  @include dashboard-container;
  
  .widget-stats {
    @include widget(1, 3, 1, 2);
  }
  
  .widget-chart {
    @include widget(4, 6, 1, 4);
  }
  
  .widget-activity {
    @include widget(10, 3, 1, 6);
  }
  
  .widget-table {
    @include widget(1, 9, 3, 8);
  }
}

Pattern 3: Magazine Layout

// Magazine-style asymmetric grid
@mixin magazine-layout {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(4, minmax(200px, auto));
  gap: 20px;
  
  .feature {
    grid-column: 1 / 5; // Spans 4 columns
    grid-row: 1 / 3;    // Spans 2 rows
  }
  
  .sidebar-1 {
    grid-column: 5 / 7; // Last 2 columns
    grid-row: 1 / 2;
  }
  
  .sidebar-2 {
    grid-column: 5 / 7;
    grid-row: 2 / 3;
  }
  
  .article {
    grid-column: span 2; // Each article spans 2 columns
    grid-row: span 1;
  }
}

.magazine {
  @include magazine-layout;
  
  @media (max-width: 768px) {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    
    .feature,
    .sidebar-1,
    .sidebar-2,
    .article {
      grid-column: 1;
      grid-row: auto;
    }
  }
}

Pattern 4: Card Gallery with Auto-Fit

// Responsive card gallery that auto-fits
$card-min-width: 280px;
$card-max-width: 1fr;

@mixin auto-grid($min: $card-min-width, $max: $card-max-width, $gap: 24px) {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax($min, $max));
  gap: $gap;
}

// Different gallery types
.gallery-compact {
  @include auto-grid(200px, 1fr, 16px);
}

.gallery-normal {
  @include auto-grid(280px, 1fr, 24px);
}

.gallery-spacious {
  @include auto-grid(350px, 1fr, 32px);
}

// Cards that span multiple columns when space allows
.featured-card {
  @media (min-width: 768px) {
    grid-column: span 2;
  }
}
Pro Pattern Use auto-fit for galleries where empty space should collapse, and auto-fill when you want to maintain empty columns.

Pattern 5: Split Screen Layout

// Full-height split layouts
@mixin split-screen($left-width: 1fr, $right-width: 1fr, $gap: 0) {
  display: grid;
  grid-template-columns: $left-width $right-width;
  gap: $gap;
  min-height: 100vh;
}

// Common split patterns
.split-50-50 {
  @include split-screen(1fr, 1fr);
}

.split-60-40 {
  @include split-screen(3fr, 2fr);
}

.split-sidebar {
  @include split-screen(300px, 1fr, 24px);
  
  @media (max-width: 768px) {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
}

Pattern 6: Grid Template Areas

// Named area layouts
@mixin app-layout {
  display: grid;
  grid-template-areas:
    "sidebar header  header"
    "sidebar content aside"
    "sidebar footer  footer";
  grid-template-columns: 250px 1fr 300px;
  grid-template-rows: 60px 1fr 80px;
  gap: 16px;
  min-height: 100vh;
  
  @media (max-width: 1024px) {
    grid-template-areas:
      "header"
      "content"
      "aside"
      "footer";
    grid-template-columns: 1fr;
    grid-template-rows: 60px 1fr auto 80px;
    
    .sidebar {
      display: none;
    }
  }
}

.app {
  @include app-layout;
  
  .sidebar { grid-area: sidebar; }
  .header  { grid-area: header; }
  .content { grid-area: content; }
  .aside   { grid-area: aside; }
  .footer  { grid-area: footer; }
}

Pattern 7: Overlapping Grid Items

// Create overlapping effects
@mixin overlap-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(6, 100px);
  
  .layer-back {
    grid-column: 1 / 8;
    grid-row: 1 / 4;
    z-index: 1;
  }
  
  .layer-front {
    grid-column: 6 / 13;
    grid-row: 2 / 6;
    z-index: 2;
  }
}

// Hero section with overlapping image and text
.hero-overlap {
  @include overlap-grid;
  
  .hero-image {
    grid-column: 1 / 9;
    grid-row: 1 / 7;
    z-index: 1;
  }
  
  .hero-text {
    grid-column: 7 / 13;
    grid-row: 3 / 6;
    z-index: 2;
    background: rgba(255, 255, 255, 0.95);
    padding: 40px;
  }
}

Pattern 8: Asymmetric Blog Layout

// Blog with varying post sizes
@mixin blog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-auto-rows: 250px;
  gap: 20px;
  
  .post-large {
    grid-row: span 2;
    grid-column: span 2;
    
    @media (max-width: 768px) {
      grid-column: span 1;
      grid-row: span 1;
    }
  }
  
  .post-tall {
    grid-row: span 2;
  }
  
  .post-wide {
    grid-column: span 2;
    
    @media (max-width: 768px) {
      grid-column: span 1;
    }
  }
}

.blog {
  @include blog-grid;
}

Combining Patterns

// Real-world example combining multiple patterns
.portfolio {
  // Outer container
  @include split-screen(300px, 1fr, 32px);
  
  .portfolio-nav {
    // Left sidebar stays fixed
    position: sticky;
    top: 0;
    height: 100vh;
  }
  
  .portfolio-main {
    // Right side uses masonry
    @include masonry-grid(3, 20px);
    
    @media (max-width: 1024px) {
      @include masonry-grid(2, 16px);
    }
  }
}
Design Tip Complex grids work best with generous whitespace. Do not be afraid of 24-32px gaps, they help users understand the structure.

Quick Check

Test your knowledge before moving to the next lesson. All 3 questions must be correct to continue.

1. What is the key technique for masonry layouts?

2. What is the difference between auto-fit and auto-fill?

3. How do you create overlapping grid items?

← Back to Learning Path