⊞CSS Grid Complete Guide
← Real-World Layouts

πŸ–ΌοΈ Photo Gallery

A grid photo gallery where images have varying aspect ratios. Dense auto-placement fills gaps automatically, creating a compact mosaic. No JavaScript positioning β€” pure CSS Grid.

grid-auto-flow: densegrid-column: span Ngrid-row: span Ngrid-auto-rows

1. Dense Photo Gallery

Each photo has a type: portrait (tall), landscape (wide), featured (large), or standard. Dense packing fills any gaps left by larger photos by backtracking and finding smaller ones that fit.

Live Demo
πŸ”οΈMountain Peak
2Γ—2
🌊
1Γ—1
🌲Forest
1Γ—2
πŸŒ…
1Γ—1
πŸ™οΈCityscape
2Γ—1
🌸
1Γ—1
β›΅
1Γ—1
πŸŒ„Dusk Panorama
2Γ—1
πŸ¦‹
1Γ—1
πŸ‹Whale
1Γ—2
🌺
1Γ—1
🏞️Valley
2Γ—1
πŸ¦…
1Γ—1
πŸŒ‹Volcano
2Γ—2
🦁
1Γ—1
CSS
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 70px;     /* base unit */
  grid-auto-flow: dense;    /* fill gaps! */
  gap: 6px;
}

/* Photo types */
.portrait  { grid-row: span 2;    } /* tall */
.landscape { grid-column: span 2; } /* wide */
.featured  {
  grid-column: span 2;
  grid-row: span 2;
} /* large: 2Γ—2 */
.standard  { /* default: 1Γ—1 */ }
πŸ’‘ The number labels (1Γ—1, 2Γ—1, etc.) show each photo's span. Without dense packing, all the 2Γ—2 and 2Γ—1 photos would leave visible holes.

2. Without Dense vs With Dense

See exactly what dense packing does. Without it, large items create holes that are never filled. With it, smaller items backfill those gaps β€” creating a tight, compact layout.

Live Demo
Without dense β€” holes visible
With dense β€” no holes
CSS
/* Without dense: holes appear */
.gallery-normal {
  grid-auto-flow: row; /* default */
}

/* With dense: holes are filled */
.gallery-dense {
  grid-auto-flow: dense; /* or: row dense */
}

/* ⚠️ Dense changes visual order!
   Later items may appear before earlier items.
   OK for visual galleries, bad for ordered content */
πŸ’‘ Dense packing reorders items visually to fill gaps. This is perfect for galleries but not for content where reading order matters (like articles or lists).

3. Responsive Column Count

Combine auto-fill with dense to get a gallery that's both responsive (fills available width) and compact (no gaps). The browser picks the column count automatically.

Live Demo
πŸ”οΈ
🌊
🌲
πŸŒ…
πŸ™οΈ
🌸
β›΅
πŸŒ„
πŸ¦‹
πŸ‹
🌺
🏞️
CSS
.gallery {
  display: grid;
  /* responsive: fills screen with cols */
  grid-template-columns:
    repeat(auto-fill, minmax(150px, 1fr));
  grid-auto-rows: 150px;
  grid-auto-flow: dense;
  gap: 8px;
}
/* Works at any screen size! */

4. Gallery with Hover Captions

Use CSS Grid's position + overlay technique to add captions on hover. The item itself is a grid container, and the caption is placed in the same cell as the image.

Live Demo
CSS
.gallery-item {
  display: grid;
  grid-template: 1fr / 1fr; /* 1 cell */
}

/* Both image and caption placed in same cell */
.gallery-item > * {
  grid-area: 1 / 1; /* all items overlap */
}

.gallery-caption {
  opacity: 0;
  transition: opacity 0.2s;
  background: rgba(0,0,0,0.5);
}

.gallery-item:hover .gallery-caption {
  opacity: 1;
}
πŸ’‘ Placing multiple items in the same grid cell (grid-area: 1/1) is a powerful Grid technique for layering content β€” like a lighter alternative to position: absolute.