Back to blog

Why Your Page 'Needs to Zoom Out' on Mobile (And It's Probably Not What You Think)

ResetKit Team··4 min read
engineeringcssdebugging

We got a bug report that's deceptively common: "the site looks weird on mobile, you have to zoom out to see it right." No specific element mentioned, no screenshot of anything obviously broken, just a vague sense that the whole page was too wide.

That vagueness is the tell. Here's what was actually going on, and why it's easy to miss.

The wrong theory first

The instinctive guess is a viewport meta tag problem. Next.js auto-injects <meta name="viewport" content="width=device-width, initial-scale=1">, so we checked that first and ruled it out immediately. Correct, present, doing its job.

Next guess: some element with a hardcoded pixel width. A quick per-element bounding-rect scan in a headless browser turned up nothing dramatic; nothing was rendering absurdly wide on its own.

The actual cause

The real culprit was subtler: several sections used a bare grid with only a responsive column class, like:

<div class="grid lg:grid-cols-2">

No base grid-cols-1. Below the lg breakpoint, that div is just display: grid with no explicit grid-template-columns, which means a single implicit column. Implicit grid tracks default to min-width: auto, and auto for a grid item means "don't shrink below your content's natural width."

If that content includes a 72px hero headline that needs roughly 500px to lay out on one line, the grid track won't go below that width, even inside a 390px phone viewport. The whole grid, and the page around it, gets forced wider than the screen. The visual symptom is exactly "the page is zoomed in and I have to zoom out," because functionally, it is: the layout is rendering at desktop width and the phone is just showing a shrunk view of it.

The fix

Add the explicit base class:

<div class="grid grid-cols-1 lg:grid-cols-2">

grid-cols-1 in Tailwind resolves to grid-template-columns: repeat(1, minmax(0, 1fr)), and minmax(0, 1fr) is the key part. Unlike the implicit auto default, an explicit minmax(0, ...) track is allowed to shrink below its content's intrinsic size, which is exactly what a responsive layout needs.

Why this is easy to miss

Nothing about this looks wrong in a desktop browser at any width above the breakpoint. The bug only exists in the gap between "no base grid-cols class" and "viewport narrower than the breakpoint." If you only ever resize your desktop browser window to test responsiveness, you can sail right past it, because a resized desktop window still triggers the same media query behavior you'd expect. It really only shows up on an actual narrow device, or a devtools emulation that fully re-renders at that width.

The fix ended up applying to eleven separate places across the site, every grid section that had a responsive column class but no matching base one. Same root cause, same one-line fix, applied wherever it showed up.

The actual lesson

"Zoomed in on mobile" is rarely a zoom bug. It's almost always something forcing real layout width past the viewport, and comparing document.documentElement.scrollWidth to window.innerWidth will tell you immediately whether that's happening, no guessing required. From there it's a matter of finding which element is the actual offender, not the ones merely overflowing inside an intentional scroll container.

Ready to integrate?

Add password reset and 2FA to your app in about fifteen minutes. Free right now.

Start for free