Solution to the overflow-x: hidden; overflow-y: visible problem

File this one under “notes to my future self,” because I’m sure I’ll search for it again, and having a blog post written about it in my own words makes it much more likely that my own idiosyncratic search for it will turn up this post.

For reasons I don’t care to understand, the CSS overflow-x: hidden forces the browser to assume overflow-y: auto (and vice-versa). If you set one dimension’s overflow value to be hidden, the other will, by necessity, be auto, and there’s nothing you can do about it.

I have a situation where — possibly due to some other stupid mistake I made in the midst of a big code push 3 years ago — animations generated by a certain popular library cause the page to add an undesirable horizontal scroll. So I added overflow: hidden on the outer container for the page content.

But I also have this theme coded to support a semi-transparent header bar, and if that’s turned on, and the first element on the page is a cover image, I want the cover image to tuck behind the header bar, by way of negative top margin. Of course, if the container element has overflow: hidden applied, that negative top margin on the child element gets hidden.

So I tried changing overflow: hidden to overflow-x: hidden and added overflow-y: visible. Which, as I have seen, doesn’t work.

Enter CSS guru Chris Coyier. I don’t know why I didn’t find his post on this matter earlier, but I am relieved that I did, because there’s a very simple solution:

Don’t use overflow-x: hidden. Use overflow-x: clip instead. Then overflow-y: visible works, and everyone’s happy!


Update (July 11, 2025): Then again, maybe not everyone’s happy. Specifically Safari users, which includes me. There’s some way that the Animate on Scroll code is tangled up in this, but with that removed (or in some cases with that not removed, but just depending on its settings), this still doesn’t work reliably in Safari, even though Safari does supposedly support clip now.

Anyway, I realized that for my purposes there’s a simpler solution. Just set overflow-x: hidden (or maybe clip but honestly I don’t care at this point) on the body tag itself, preventing any horizontal scrolling on the page. Then you can put overflow-y: visible on the element you want to exceed its vertical boundaries, and everything seems to work. At least today. I’m sure I’ll come back to this exact code again next week and it won’t be working, and I’ll have no idea why.

I’m getting too old for this shit.