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.