There have been a number of questions like this one around the internet for dealing with horizontal scrollbars. I've read a lot of them and people explain how to fix this, but I can't find an answer as to why it happens in the first place.
The spec says the following about the hidden
overflow value:
This value indicates that the box’s content is clipped to its padding box and that the UA must not provide any scrolling user interface to view the content outside the clipping region, nor allow scrolling by direct intervention of the user, such as dragging on a touch screen or using the scrolling wheel on a mouse. However, the content must still be scrollable programatically, for example using the mechanisms defined in [CSSOM-VIEW], and the box is therefore still a scroll container.
I've made this very simple page that deliberately has overflowing content and overflow-x: hidden
on the <body>
:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="overflow-x: hidden">
<div style="width: 150%">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec maximus magna odio, vel eleifend nulla
ullamcorper eget. Nulla vel mi facilisis, facilisis mi non, lacinia libero. Cras eros orci, tristique id
orci et, finibus convallis libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Quisque vehicula mauris at ex placerat fermentum sed eget erat. Nulla eleifend sodales
dolor, ac luctus eros malesuada et. Sed ut lobortis eros. Vestibulum eget tortor nibh. Mauris vulputate
sapien id faucibus molestie. Proin commodo efficitur purus, vitae auctor libero luctus eu. Donec nec ipsum
libero. Duis tincidunt dapibus ex, vel facilisis sapien interdum id.</p>
<p>Nunc faucibus, velit at aliquet condimentum, felis urna tristique sapien, sed volutpat nibh turpis nec dolor.
Sed feugiat at justo eget auctor. Cras pellentesque dapibus orci non egestas. Nulla pulvinar rhoncus nulla
vel tempus. Sed id ultrices nisi. Cras sit amet augue eget tellus convallis condimentum a non massa. Ut a
justo in felis interdum tempus vitae vitae orci. Praesent efficitur mi dui, quis porttitor tellus
pellentesque suscipit. In posuere volutpat scelerisque. Donec semper sapien at elit egestas, sit amet
fringilla risus ultricies. Maecenas congue posuere velit, eu tristique metus cursus quis. In urna lorem,
mollis non quam ac, consectetur laoreet ante.</p>
<p>Pellentesque nec sem pellentesque, interdum dui id, pretium ipsum. Aenean at augue placerat, rutrum mauris
quis, vehicula nibh. Vestibulum at augue mi. Sed laoreet enim et augue dapibus vestibulum. Curabitur
pellentesque dignissim ante quis elementum. Phasellus pretium tortor molestie libero tincidunt eleifend vel
sed mi. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc eu finibus dui, non mattis
sapien. Pellentesque at tortor lacus. Donec enim nulla, lacinia a risus id, congue sollicitudin dolor. Fusce
non imperdiet magna. Nunc vehicula scelerisque aliquet. Mauris pellentesque quis enim vitae finibus.</p>
<p>Nulla facilisi. Maecenas vitae ipsum quam. Cras eleifend facilisis dolor vel blandit. Praesent commodo ex
arcu, id varius felis condimentum et. Nulla lobortis, augue ut ultricies tincidunt, dolor dui tristique
libero, nec lacinia tellus nunc ut risus. Phasellus et egestas arcu. Vestibulum lobortis vel erat sit amet
fringilla. Proin fringilla urna libero, eget cursus sem laoreet sed. Nunc vitae mauris et elit mollis
volutpat eu eget velit. Mauris fringilla viverra ex, nec ornare arcu consequat id. Cras sed erat elit.
Mauris euismod, sapien eu iaculis finibus, massa risus convallis eros, sit amet lacinia lacus velit
elementum arcu. Etiam ut lacus convallis, euismod enim eu, bibendum libero.</p>
<p>Maecenas auctor sapien auctor lobortis auctor. Praesent vel lacus dictum, rutrum dui vitae, vehicula arcu.
Aenean sapien ante, dignissim ut lacinia quis, interdum faucibus lacus. Mauris facilisis dolor non orci
interdum, eget suscipit orci cursus. Quisque a eros quam. Etiam tempor nisi vel iaculis luctus. Fusce sit
amet pellentesque erat. In lorem mi, mattis ut maximus semper, efficitur eget eros. Suspendisse ac nulla
tincidunt enim tincidunt convallis sit amet ac nisl. In eu magna libero. Aliquam erat volutpat. In egestas
sit amet mauris a rhoncus. Aliquam aliquet mauris nec venenatis dignissim. Aenean faucibus tortor vitae
lacus malesuada, id fringilla nunc tincidunt.</p>
</div>
</body>
</html>
...and on desktop, the horizontal scrollbar is correctly hidden:
However, on a mobile device, you can scroll the content:
You even get a scrollbar in DevTools when viewing the page in "Mobile" mode:
The question is why? I have the meta viewport tag in the page:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
...which is a hint that the page is mobile-friendly. Therefore if I have overflow-x: hidden
, I mean it. Why doesn't the browser respect that?
I know I can get around this by wrapping the entire page in a <div>
element, for example, and setting overflow-x: hidden
on that instead. But if I have a position: sticky
element somewhere in the content, it would no longer work because it sticks to its scroll container, which is the wrapper element, and the actual scroll happens on the body. Or, if I also set overflow-y: auto
on the wrapper, the sticky element will work as expected, but now all the JavaScript will break because it uses document.scrollingElement
, and the actual scrolling element is this wrapper.
So getting around this can be tricky, and I don't understand why we need those hacks. To me, it appears that browsers fail to implement the spec correctly.