Back to CSS
CSS
hard
mid

How would you design a responsive grid layout using CSS Grid and Flexbox?

Use CSS Grid for the responsive grid: `grid-template-columns: repeat(auto-fill, minmax(min, 1fr))` adapts column count to viewport with zero media queries; add `gap` for spacing. Use Flexbox inside each cell for its internal layout. Layer in `clamp()` for fluid sizing and a few media queries only for major layout changes.

6 min read·~20 min to think through

A responsive grid is the canonical "show me you know modern CSS layout" question. The modern answer needs almost no media queries.

The core: intrinsic responsive grid

css
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.5rem;
}

This one line is responsive without a single media query:

  • minmax(240px, 1fr) — each column is at least 240px, but grows to share leftover space equally (1fr).
  • repeat(auto-fill, ...) — fit as many 240px+ columns as the container allows; reflow the count automatically as the viewport changes.
  • gap — consistent gutters, no margin hacks.

auto-fill vs auto-fit: auto-fill keeps empty tracks (items stay their min size); auto-fit collapses empty tracks so items stretch to fill the row. Use auto-fit when you want items to expand on wide screens, auto-fill when you want a stable column rhythm.

Flexbox for the cell internals

Grid places the cards; Flexbox lays out what's inside each card:

css
.card {
  display: flex;
  flex-direction: column;
}
.card__body { flex: 1; }          /* push the footer down */
.card__footer { margin-top: auto; }

This Grid-outside / Flexbox-inside split is the standard real-world pattern.

Fluid sizing with clamp()

css
.grid { gap: clamp(1rem, 2vw, 2rem); }
.card { padding: clamp(1rem, 3vw, 2rem); }
h2 { font-size: clamp(1.25rem, 2vw + 1rem, 2rem); }

clamp(min, preferred, max) scales smoothly between breakpoints — fewer media queries for type and spacing.

Media queries only for real layout changes

Keep them for structural shifts the intrinsic grid can't express:

css
.page {
  display: grid;
  grid-template-columns: 1fr;            /* mobile: stacked */
}
@media (min-width: 768px) {
  .page { grid-template-columns: 240px 1fr; }  /* tablet+: sidebar + content */
}

Container queries — the modern upgrade

For a reusable grid component that should respond to its own container, not the viewport:

css
.card-container { container-type: inline-size; }
@container (min-width: 400px) {
  .card { flex-direction: row; }
}

Checklist for the interview

  1. Grid + repeat(auto-fill/fit, minmax()) + gap for the responsive grid.
  2. Flexbox inside cells.
  3. clamp() for fluid type/spacing.
  4. Media queries only for major structural changes.
  5. Mention container queries for true component reusability.
  6. Don't forget images: aspect-ratio / object-fit: cover so cards don't jump.

Senior framing

The senior answer shows you've moved past "breakpoint soup": the minmax/auto-fill grid is intrinsically responsive, clamp handles fluid scaling, and media/container queries are reserved for genuine structural changes. Knowing auto-fill vs auto-fit and when to reach for container queries is the depth signal.

Follow-up questions

  • What's the difference between auto-fill and auto-fit?
  • When would you use a container query instead of a media query?
  • How does clamp() reduce the need for media queries?

Common mistakes

  • Building the grid with floats or many fixed-width media queries.
  • Using Flexbox for a true 2D grid and fighting wrap behavior.
  • Forgetting `gap` and using margin hacks.
  • Not constraining card images (layout jumps).

Edge cases

  • auto-fit collapses empty tracks — a single item stretches full-width, which may be undesirable.
  • minmax with a min larger than the container causes overflow.
  • Container queries need container-type on an ancestor.

Real-world examples

  • Product galleries, dashboards, image grids, card-based feeds.

Related questions