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.


