4 min read
Why your page scrolls sideways on mobile
The element that looks broken is almost never the one you have to fix. A short explanation of min-width: auto, and the one-line fix.
You open your site on a phone, swipe left, and the whole page slides. There is a strip of empty background on the right that should not exist. Nothing looks obviously wrong, and you have already set overflow-x: auto on the thing you suspect.
I have hit this on three different projects now, and it is the same cause every time.
The usual first attempt
A long line of code is spilling out of the article, so you give it a scroll container:
pre {
overflow-x: auto;
}That should be it. The code block becomes its own scrollable box and the page stays put.
Except the page still slides.
What is actually happening
overflow-x: auto only works if the element is allowed to be narrower than its contents. If something is forcing the box to grow, there is nothing to overflow out of, and the scrollbar never appears.
The thing forcing it to grow is usually its parent, and the reason is a default most people never read:
Flex and grid items have
min-width: auto.
In plain language: a flex or grid child refuses to shrink below the width of its own content. Put a 900px-wide code block inside a grid column, and that column becomes at least 900px wide. The grid becomes wider. The page becomes wider. The phone gives you a horizontal scrollbar.
The code block was never the problem. It was doing exactly what you told it. The column above it was quietly ignoring the layout.
The fix
Give the flex or grid child permission to shrink:
.column {
min-width: 0;
}In Tailwind that is min-w-0:
<div class="grid lg:grid-cols-12">
<div class="min-w-0 lg:col-span-8">
<article>...</article>
</div>
</div>Now the column can be narrower than its content, so the code block's overflow-x: auto has something to do, and the page stops moving.
For flex rows you often need min-width: 0 on the item that holds text, for the same reason. flex-shrink: 1 is already the default, but min-width: auto cancels it out — which is why flex-1 alone frequently does not stop overflow.
Why this default exists
It is not a mistake. Before this rule, a flex item could be squashed down to zero and its content would vanish off the edge with no way to reach it. Refusing to shrink past the content is the safer default for most layouts.
It stops being safer the moment a child is supposed to scroll on its own: code blocks, tables, image carousels, anything with overflow set. For those, you are opting out deliberately, and min-width: 0 is how you say so.
Finding the culprit
Paste this into the browser console on the broken page:
document.querySelectorAll("*").forEach((el) => {
if (el.getBoundingClientRect().right > document.documentElement.clientWidth + 1) {
console.log(el.className || el.tagName, el);
}
});It walks every element and logs the ones sticking out past the viewport. The list reads outside-in: the first entries are usually the containers, and somewhere near the end is the actual wide thing.
Fix the outermost flex or grid ancestor first. Often that is the only change needed, because once the parent can shrink, the children inside it behave.
Other causes worth ruling out
min-width: auto is the one that wastes the most time, but it is not the only way a page ends up too wide:
- A long unbroken string — a URL, a long environment variable name, a hash. There is no space to wrap at.
overflow-wrap: anywhereon the text container handles it. - A fixed width in pixels on something that should be fluid.
width: 600pxis wider than a 360px phone. - Negative margins used to pull something out of its container, which does exactly that on a narrow screen.
100vw— this includes the vertical scrollbar's width on desktop, so an element atwidth: 100vwis slightly wider than the space available. Use100%instead.- A table. Tables size themselves to their content and ignore the usual rules. Wrapping one in
display: block; overflow-x: autois the standard fix.
The habit worth building
When a page scrolls sideways, resist fixing the element that looks wrong. Walk up its ancestors first and ask which one is refusing to shrink.
The wide element is the symptom. The parent is the cause. CSS is full of problems shaped like this, and once you have seen this one, you start looking upward by instinct.