Technote

Themes & plugins Practical

Series Layouts that hold up on mobile Part 5 of 8

Hunting horizontal overflow — the number will not find it

scrollWidth matches the viewport and yet the screen is visibly clipped. An ancestor absorbed the overflow — so measure element rectangles instead.

When a page shifts sideways on a phone, the first move is usually to check document.documentElement.scrollWidth in the console. If it exceeds the viewport, something is overflowing. The trouble is that the number can look perfectly correct while the screen is visibly clipped.

The number is fine, the screen is not

If some ancestor in the middle carries overflow: hidden, anything overflowing inside it is cut off right there. As far as the document is concerned nothing overflows, so scrollWidth equals the viewport exactly. Meanwhile the right edge of a card is sliced off and half a button has disappeared.

The reverse happens too: a large scrollWidth while every visible element sits where it should, because a decorative element or a closed menu panel is parked off-screen. Either way, a single document-level number cannot tell you where the problem is.

Two ways of looking at one symptom, with very different information

Finding the culprit by rectangle

Measure every element and keep the ones crossing the viewport edge. This pastes straight into the console.

const w = document.documentElement.clientWidth; [...document.querySelectorAll('*')].filter(el => { const r = el.getBoundingClientRect(); return r.right > w + 1 || r.left < -1; }).slice(0, 20);

Expect several results — when a child is pushed out, its ancestors go with it. So read from the deepest element backwards; the real cause is usually there. To confirm, give that element a temporary outline: 2px solid and it becomes obvious on screen.

Five common causes

The usual causes of horizontal overflow — the first line comes up most often

That first line deserves a note. 100vw includes the vertical scrollbar, so wherever a scrollbar takes up space it is always wider than the content area. Building a full-bleed background with something like margin-left: calc(50% - 50vw) adds a second failure: if the element is not horizontally centred, one side lands in the wrong place — which it will be next to any off-centre layout such as a table-of-contents rail. If you need a full-bleed band, make that section itself full width instead.

Do not paper over it with overflow-x: hidden

The quickest-looking fix is body { overflow-x: hidden; }. The symptom vanishes, the cause does not, and there are two costs. The overflowing element is still off-screen, so part of it stays clipped; and hiding one axis while leaving the other visible makes the visible axis compute to a scrolling value.

That second cost is the quiet one. Once you have created a scroll container, every position: sticky inside it stops working — no error, no warning, it simply does not stick. The final part of this series is about exactly that.

Turning front-end checks into a repeatable routine is covered in the development workflow archive, and the diagnostic plugin we publish is on the free tools page.

Next part

With the layout holding still, the next question is operating it. Next: tap target sizes, and where a cursor-designed interface fails under a fingertip.

More on this topic

All technotes

Themes & plugins Practical

Decide the editable regions before you design them

A design the CMS cannot express stays up for negotiation long after it ships. Deciding what editors may change, first, removes the negotiation entirely.

Designers 6 min read

₩270,000 · Join the program