How to find what is actually causing horizontal scroll

The element sticking off the right edge is usually a symptom. The rule you need to change is normally on a parent, several levels up.

You narrow the browser, a horizontal scrollbar appears, and something is off-screen. The standard advice is to find the wide element and constrain it. That advice is incomplete, and it is why this bug takes so long to fix.

Why the obvious element is the wrong one

Consider a dashboard shell with this layout:

.layout { display: grid; grid-template-columns: 1fr 372px; }

At a 344px viewport, that fixed 372px track alone is wider than the screen. Everything inside the page gets pushed right: the toolbar buttons, the nav tabs, the sidebar itself. Inspect the page and you will find four or five elements overflowing. Constrain any one of them and the scrollbar stays, because none of them is the cause. One line on .layout fixes all of it.

Rule of thumb

Walk up from the overflowing element toward the body. The first ancestor with a fixed width, a fixed grid track, or a non-wrapping flex row is your culprit. Stop climbing if you hit an ancestor that already scrolls internally - the problem is contained below it.

The eight causes, in the order they occur

CauseFix
grid-template-columns with a fixed px trackStack at a breakpoint, or use minmax(0, 372px)
Non-wrapping flex rowflex-wrap: wrap, plus min-width: 0 on children
width in px larger than the viewportwidth: 100%; max-width: [the px value]
min-width larger than the viewportmin-width: 0
width: 100vwwidth: 100% - 100vw includes the scrollbar
white-space: nowrapAllow wrapping, or overflow-x: auto on that box
Image or iframe with no max-widthimg, iframe { max-width: 100%; }
Table wider than its containerWrap it in a div with overflow-x: auto

Why overflow-x: hidden is not a fix

Adding overflow-x: hidden to the body removes the scrollbar and leaves the content unreachable. Anything past the edge is now genuinely inaccessible rather than awkwardly accessible. It also breaks position: sticky in many cases. Use it only as a deliberate containment on a specific box, never as a page-level patch.

Finding it by hand

In DevTools, dock the panel to the side - undocked, Chrome will not let you narrow the viewport below about 500px, which is wider than every phone. Then use Elements > Layout > Overflow, or paste this in the console:

document.querySelectorAll('*').forEach(el => {
  if (el.getBoundingClientRect().right > document.documentElement.clientWidth)
    console.log(el);
});

That lists the symptoms. You still walk up the tree yourself to find the cause.

A free tool that does part of this well

Overflow Finder is a free DevTools extension that ranks overflowing elements and guesses a cause for each. If you only need culprit-finding at your current window size, it does that job and costs nothing. What it does not do is check every viewport at once, or trace the cause up to the parent that owns it.

Common questions

Why does the scrollbar appear at some widths and not others?

Because the overflowing element only exceeds the viewport below a certain width. A 372px sidebar is fine at 1280px and impossible at 344px. That is also why testing one narrow width is not enough - different causes trigger at different points.

Does 100vw really cause overflow?

Yes, on any page with a vertical scrollbar. 100vw is the full viewport width including the scrollbar gutter, while the visible content area is narrower by roughly 15px. Using width: 100% instead resolves it because percentages resolve against the containing block, which excludes the scrollbar.

My overflow only appears after the page loads. Why?

Something injected content after the initial render - an ad slot, a chat widget, a consent banner, or a web font that changed text width. Re-run your check after the page settles, and inspect third-party embeds first, since they commonly carry fixed pixel widths.

What is min-width: 0 and why does it fix flex overflow?

Flex and grid items default to min-width: auto, which means they refuse to shrink below their content's intrinsic minimum size. A long word or a wide child then forces the item wider than its track. Setting min-width: 0 permits shrinking, which is usually what you intended.

Get told when it ships

A scan that names the parent responsible - not just the element sticking out - and gives you the CSS to change, at every viewport at once.

One email when it is ready. No newsletter, no sharing, unsubscribe in one click. Questions: support@hakeemify.com

Related guides