SCSS • LEVEL 3 • LESSON 7 OF 9
0% Complete
← Back to Learning Path

🎯 Lesson 7: Advanced Grid Patterns

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

Beyond Basic Grids

You've mastered the fundamentals. Now let's tackle advanced patterns that solve real-world layout challenges. We'll 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. Don't be afraid of 24-32px gaps - they help users understand the structure.

📝 Quick Check (3 Questions)

1. What's the key technique for masonry layouts?

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

3. How do you create overlapping grid items?

← Back to Learning Path