That sideways scroll on your phone? Find and fix it from the console
That unwanted left-to-right scroll on mobile (and desktop) is almost always one element that is too wide. Here is how to find the exact culprit from the browser console and fix it in a line or two of CSS.
You open your site on a phone, swipe, and the whole page slides a little to the left and right. Nothing is supposed to move sideways, but it does. There is a thin strip of empty space on the edge, and the layout feels loose and broken.
This is one of the most common layout bugs on the web, and almost everyone hits it. It is usually called horizontal scroll, or horizontal overflow. People often describe it loosely as "the scroll problem" because it feels like the page is scrolling in a direction it should not. The good news is that it is very findable. You do not need to guess. The browser console can tell you the exact element that is too wide, and the fix is usually one or two lines of CSS.
This post walks through the whole thing in general terms, so you can use it on any project, mobile or desktop.
First, a quick word on the console
Every browser ships with developer tools. Press F12 on Windows or Linux, or Cmd + Option + I on a Mac, and a panel opens. One of its tabs is the Console. The Console is a live JavaScript prompt that runs against the page you are looking at right now. Whatever you type runs immediately, with full access to the page and its elements.
That last part is what makes it perfect for hunting layout bugs. You are not reading static code. You are asking the real, rendered page questions like "how wide are you actually?" and "which element is sticking out past the edge?"
To test mobile behavior without a phone, open the dev tools and click the device toolbar icon (it looks like a small phone next to a tablet, usually top left of the dev tools panel). Pick a device like iPhone or Pixel. Now the page renders at phone width and you can debug it on your desktop.
Why horizontal scroll happens
The page scrolls sideways when something inside it is wider than the screen. The browser will not crop your content by default. If one element pokes past the right edge, the browser adds horizontal scroll so the user can reach it.
The usual suspects are:
width: 1200pxor any other fixed width, on a screen narrower than that.100vwused as a width.vwdoes not subtract the scrollbar, so it can be a few pixels wider than the visible area.margin-left: -20pxand other negative margins that pull an element past the edge.- Large padding on a full width element when
box-sizing: border-boxis not set. - A long unbroken string of text or a wide code block that refuses to wrap.
- An image or video with no
max-width: 100%. - A transformed or absolutely positioned decorative layer (a blurred background, a rotated card, an offset glow) that bleeds past its container.
Notice the theme. It is almost always one specific element, not the whole layout. So the job is to find that one element.
Step one: confirm there really is overflow
Open the Console and run this:
const de = document.documentElement;
console.log('overflow px =', de.scrollWidth - de.clientWidth);clientWidth is how wide the visible area is. scrollWidth is how wide the content actually is, including anything that spills past the edge. If scrollWidth is bigger than clientWidth, that difference is your overflow in pixels. If it prints 0, there is no horizontal overflow at the page level, and whatever you are seeing is something else (more on that at the end).
Step two: find the element that sticks out
Now ask the page which elements extend past the right edge, widest first:
const vw = innerWidth;
[...document.querySelectorAll('body *')]
.map(el => ({ el, r: el.getBoundingClientRect() }))
.filter(({ r }) => r.right > vw + 1 || r.left < -1)
.sort((a, b) => (b.r.right - b.r.left) - (a.r.right - a.r.left))
.slice(0, 8)
.forEach(({ el, r }) => console.log(
Math.round(r.left) + ' to ' + Math.round(r.right) + ' ' +
el.tagName + '.' + (el.className || '(no class)')
));
console.log('viewport =', vw);Here is what each part does:
document.querySelectorAll('body *')grabs every element on the page.getBoundingClientRect()gives the real on screen position of each one, including its left and right edge in pixels.- The
filterkeeps only elements whose right edge is past the viewport width, or whose left edge is in negative space (off the left side). The+ 1and- 1ignore harmless rounding. - The
sortputs the widest offenders first, andslice(0, 8)keeps the list short. - Each line prints as "left to right" plus the tag and class, so you can recognize the element.
You will get something like -21 to 452 IMG.card-background with a viewport of 430. That tells you an image starts 21 pixels off the left edge and ends 22 pixels past the right. There is your culprit.
Step three: identify exactly what it is
Sometimes the offending element has no class, or there are several of them. Print a short parent chain so you know which component it belongs to:
const vw = innerWidth;
[...document.querySelectorAll('body *')]
.map(el => ({ el, r: el.getBoundingClientRect() }))
.filter(({ r }) => r.right > vw + 1 || r.left < -1)
.sort((a, b) => (b.r.right - b.r.left) - (a.r.right - a.r.left))
.slice(0, 4)
.forEach(({ el }) => {
const chain = [];
let n = el;
for (let i = 0; i < 5 && n; i++, n = n.parentElement)
chain.push(n.tagName + (n.className ? '.' + String(n.className).replace(/\s+/g, '.') : ''));
console.log(chain.join(' < '));
});This climbs up to five levels from the offending element to its ancestors and prints the path, like IMG < DIV.card-bg < DIV.card-image < A.card. Now you know the component, not just a mystery element.
Step four: fix the cause
Once you know the element, the fix depends on why it is wide. The common ones:
* { box-sizing: border-box; } /* padding never widens the box */
img, video { max-width: 100%; display: block; }
.full-width { width: 100%; } /* prefer 100% over 100vw */
.text { overflow-wrap: break-word; } /* wrap long words and URLs */If the wide element is a decorative layer that is supposed to be bigger than its box (a blurred background, an offset shape), you do not want to resize it, you want to contain it. Clip it at the container:
.container {
overflow: clip;
}overflow: clip is usually a better choice than overflow: hidden here. hidden creates a scroll container, which can interfere with sticky positioning and smooth scroll libraries. clip just clips and does not create a scroll container, so the rest of your layout keeps behaving normally.
The last resort, and a desktop note
If you cannot easily track down every leak, or you want a guarantee, you can clip the whole page on the horizontal axis:
html {
overflow-x: clip;
}This stops the page from ever scrolling sideways. Use it as a safety net, not as a substitute for finding the cause, because it hides the symptom rather than fixing the wide element. Hiding a real layout problem can bite you later when content actually needs that space.
A quick word on desktop. Horizontal scroll is not only a phone problem. It shows up on desktop too, especially at smaller window widths or when someone zooms in. The detection steps above work exactly the same. Just resize your browser narrow, or zoom to 150 percent, and run the same console checks. If your layout overflows when the window gets small, the same one element is usually to blame.
A gotcha worth knowing: mobile browsers are not all the same
Here is a subtle trap. You run the overflow check in Chrome, it prints 0, everything looks contained, and yet a real iPhone still scrolls sideways. How?
Browsers do not all clip content identically. In particular, when an element is transformed (for example transform: scale(1.1) to cover an edge), Chrome will contain that scaled overflow with overflow: clip, but Safari on iOS has historically let a transformed child leak past the clip anyway. So Chrome reports no overflow while Safari still scrolls.
If you suspect this, two things help. First, add clip-path: inset(0) to the container alongside overflow: clip. clip-path clips transformed descendants more reliably across browsers. Second, when possible, test on a real device, because device mode in Chrome emulates the size but not every quirk of the actual mobile engine.
The recap
- Open the Console (
F12), and switch on device mode to test at phone width. - Run
scrollWidth - clientWidthto confirm there is real overflow and see how many pixels. - Run the detector snippet to list elements sticking past the edge, widest first.
- Run the parent chain snippet to identify which component it belongs to.
- Fix the cause:
box-sizing,max-widthon media,100%instead of100vw, wrapping for long text, oroverflow: clipon a container for decorative bleed. - Use
html { overflow-x: clip }only as a safety net. - If Chrome says zero but a real phone still scrolls, suspect a transformed child and reach for
clip-path: inset(0), then test on a real device.
The whole point is that you never have to guess. The page already knows which element is too wide. You just have to ask it.


