Why Your CSS Grid Breaks on Mobile (and the One-Line Fix)
If a CSS grid column overflows on phones and clips your content — text, tables or code cut off on the right, yet no horizontal scrollbar appears — the culprit is almost always a 1fr track that refuses to shrink. A grid 1fr column has an implicit min-width: auto, so a wide child (a table or a <pre> block) pushes the track wider than the screen, and an ancestor with overflow-x: hidden then clips the overflow instead of scrolling it. The fix is one property: min-width: 0 on the grid items (or minmax(0, 1fr) on the track).
What you’ll learn: why 1fr silently blows out, why your responsive breakpoints don’t save you, and the exact two changes that fix it — measured on a real layout.
Evidence note: based on a real overflow bug on my own WordPress site’s article template. The CSS shown is the live fix; the before/after widths are from a 375px viewport audit I ran on 2026-07-31.
The symptom
My single-post layout is a two-column grid — article on the left, sidebar on the right:
.mca-single-layout {
display: grid;
grid-template-columns: 1fr 320px;
}
On desktop it’s perfect. On a 375px phone, the right edge of every paragraph, image and table was sliced off — and, confusingly, there was no horizontal scrollbar to hint at overflow. The content was just… gone past the right edge.
When I measured the article column at a 375px viewport, it was 571px wide — wider than the screen. Something inside it was forcing it open.
The fixes that didn’t work
- "The breakpoint will handle it." I had a media query collapsing the grid to a single column on mobile. It fired — and the column was still 571px. Stacking the columns doesn’t help if one column refuses to be narrower than its widest child.
- Hiding the overflow. An ancestor had
overflow-x: hidden(a common "stop the page scrolling sideways" reflex). That’s exactly what turned an overflow into a clip: the content still rendered at 571px, but everything past the viewport edge was simply cut off with no way to reach it.
The root cause
The gear I run for this
Hardware from my own homelab, relevant to this guide — direct Amazon links.
Affiliate links — I earn a small commission at no extra cost to you. Browse my full homelab store →
This is the part that isn’t obvious. A grid track defined as 1fr doesn’t mean "take the remaining space and never exceed it." A 1fr track carries an implicit min-width: auto, and auto resolves to the min-content size of the track’s contents.
If any child can’t shrink below a certain width — a <table> with many columns, a <pre> block with a long line of code, a fixed-width image — then the track’s min-content is that width. The 1fr track dutifully grows to fit it, straight past the viewport. Add overflow-x: hidden on a parent and the excess is clipped instead of scrolled, so you get invisible, unreachable content and no scrollbar.
In short: 1fr will not shrink below its widest indivisible child unless you tell it it’s allowed to.
The fix
Two changes. The first is the one-liner that matters most.
1. Let the track shrink — min-width: 0. Override the implicit min-width: auto on the grid items:
.mca-single-layout > *,
.mca-single-article,
.mca-single-article__body,
.mca-single-sidebar {
min-width: 0;
}
Equivalently, you can do it on the track itself with minmax(0, 1fr):
.mca-single-layout {
grid-template-columns: minmax(0, 1fr) 320px;
}
Both say the same thing: this column is allowed to be narrower than its content’s min-content width.
2. Give wide children somewhere to go — scroll, don’t force. min-width: 0 lets the column shrink, but now a wide table would overflow the column. So wrap wide tables (and constrain <pre>) to scroll within their own box instead of pushing width outward:
.mca-table-scroll {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
max-width: 100%;
margin: 1.3rem 0;
}
.mca-single-article__body pre {
min-width: 0;
}
Wrap each wide table:
<div class="mca-table-scroll">
<table> … </table>
</div>
After both changes, the same article column at a 375px viewport measured 351px — down from 571px — with zero clipped elements. Tables now scroll inside their own container; everything else fits.
Why the obvious fixes fail
| What you tried | Why it didn’t work |
|---|---|
| Add a mobile breakpoint | Collapsing to one column doesn’t remove the min-width: auto floor; the column stays as wide as its widest child. |
overflow-x: hidden on a parent | Converts the overflow into an invisible clip — worse than a scrollbar, because the content is unreachable. |
width: 100% / max-width: 100% on the column | The 1fr track’s min-content still wins; the track computes wider than 100% before your cap applies. |
A reusable checklist
- Column overflowing on mobile? Add
min-width: 0to the grid items (orminmax(0, 1fr)to the track). This alone fixes most cases. - Wrap wide tables in an
overflow-x: autocontainer so they scroll instead of forcing width. - Give
<pre>blocksmin-width: 0(and let them scroll) for the same reason. - Audit at 375px: check the computed width of the content column is ≤ viewport, and that nothing is clipped.
- Use
overflow-x: hiddenon the body as a last resort only — it hides symptoms and can clip real content.
Takeaway
1fr is not a promise to stay within bounds — it carries an implicit min-width: auto that lets one stubborn table or code block blow the whole column past the viewport, and overflow-x: hidden then hides the evidence. The moment a grid column overflows on mobile, reach for min-width: 0 (or minmax(0, 1fr)) first. It’s framework-agnostic — the same trap and the same fix apply whether you’re in WordPress, React, or plain HTML.
AI assisted with drafting; the layout, the bug, the fix, and the width measurements are from my own site.
Leave a Reply