I spent way too long last night fighting flexbox on a mobile layout.

The problem: filter buttons that wrapped unevenly on small screens.

The solution: CSS Grid.

Here’s what I learned.


The Problem: Uneven Flexbox Wrapping

I had a row of category filter buttons:

  • All Posts
  • Business
  • Events
  • Faith
  • FBL Updates
  • Leadership

Flexbox approach:

.filter-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

What happened on mobile:

[All Posts] [Business] [Events]
[Faith] [FBL Updates]
[Leadership]

Three on the first row. Two on the second. One lonely button on the third.

It looked terrible.


Why Flexbox Struggles on Mobile

Flexbox is content-based. It wraps items based on their intrinsic width.

If “All Posts” is 90px wide and “FBL Updates” is 120px wide, flexbox doesn’t care about creating balanced rows. It just wraps when it runs out of space.

On mobile (375px width):

  • First row: 90px + 95px + 80px = 265px ✅ (fits)
  • Second row: 70px + 120px = 190px ✅ (fits)
  • Third row: 105px = 105px (orphan)

Flexbox did its job. The result still looked awkward.


The Grid Solution

CSS Grid gives you control:

.filter-buttons {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

Result on mobile:

[All Posts]      [Business]
[Events]         [Faith]
[FBL Updates]    [Leadership]

Clean. Balanced. Symmetrical.

Every button is the same width (1fr = equal fractions). No orphans. No awkward wrapping.


When to Use Grid vs Flexbox

Use Flexbox when:

✅ Content width should dictate layout
✅ Items vary significantly in size
✅ You want natural wrapping (like tag clouds)
✅ Single-axis alignment (row OR column)

Example: Navigation links

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

Links vary in length (“Home” vs “Documentation”). Let them be different widths.


Use Grid when:

✅ You want uniform sizing
✅ You need predictable multi-column layouts
✅ Visual balance matters more than content width
✅ You want explicit control over rows/columns

Example: Filter buttons (mobile)

.filter-buttons {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

Buttons should look uniform and balanced on small screens.


Mobile-First Grid Strategy

Here’s the pattern I use:

Mobile: Grid (control)

.filter-buttons {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

Desktop: Flexbox (natural flow)

@media (min-width: 769px) {
  .filter-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
  }
}

Why switch at desktop?

  • Mobile (375px): Grid keeps buttons balanced
  • Desktop (1200px+): Flexbox lets buttons flow naturally in one row

You get the best of both.


The Three-Column Trap

Don’t do this on mobile:

.filter-buttons {
  display: grid;
  grid-template-columns: repeat(3, 1fr);  /* ❌ Too cramped */
}

Three columns on a 375px screen means ~100px per button (minus gaps). Your text will wrap inside the buttons, creating multi-line button labels.

Terrible UX.

Stick to 2 columns max on mobile.


Practical Example: Blog Archive Grid

Yesterday I fixed a blog card grid with the same issue.

Problem:

.blog-archive-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);  /* Desktop default */
}

On mobile, two blog cards side-by-side looked cramped. Images were tiny. Text wrapped awkwardly.

Solution: Mobile-first approach

.blog-archive-grid {
  grid-template-columns: 1fr;  /* Mobile: stack vertically */
}

@media (min-width: 769px) {
  .blog-archive-grid {
    grid-template-columns: repeat(2, 1fr);  /* Desktop: 2 columns */
  }
}

Mobile gets full-width cards. Desktop gets the 2-column layout.

One grid property. Dramatically better mobile experience.


Quick Decision Matrix

Layout NeedMobileDesktop
Filter buttonsGrid (2 cols)Flexbox (flow)
Blog cardsGrid (1 col)Grid (2-3 cols)
Navigation linksFlexboxFlexbox
Product gridGrid (2 cols)Grid (3-4 cols)
Tag cloudFlexboxFlexbox

The Lesson

Flexbox is amazing. Grid is amazing.

But they solve different problems.

Flexbox: “Let the content flow and wrap naturally.”
Grid: “I want explicit control over columns and rows.”

On mobile, where screen space is tight and visual balance matters, Grid often wins.


Takeaway

Before you default to flexbox for everything:

  1. Ask: Do I need explicit column control?
  2. Check mobile: Does uneven wrapping look okay?
  3. Consider Grid: 2-column grids are clean and balanced on mobile

Your mobile users won’t notice the CSS.

They’ll just notice it looks better.


Tools:

  • Chrome DevTools mobile viewport
  • CSS Grid Inspector (Firefox)
  • Hugo static site generator

Related:

  • Mobile-first CSS
  • Responsive grid patterns
  • Touch target sizing