Single-Directionally Allowed Overflow

There is this annoying thing in CSS where it feels like you should be able to hide overflow in one direction and allow it in another, since they can be separate properties:

.nav-bar {
  overflow-x: hidden;
  overflow-y: visible;
}Code language: CSS (css)

But you’ll be disappointed.

I really wish I could explain to you why you can’t do that, but I don’t know the historical CSS discussions that got us here. People clearly want to do it sometimes. I know, I’ve read tons of threads about it. The most common use case is something like an app sidebar along the left of a layout which can scroll vertically, but allows for menus that can extend out of it to the right. Another use case is a header bar on top of a site that hides the horizontal overflow but allows for vertical (sometimes a nice protection to avoid awkward “page zoom outs” with content that accidentally overflows).

Good news: you can do it with the clip value

This does work:

.nav-bar {
  overflow-x: clip;
  overflow-y: visible;
}
Code language: CSS (css)

Here’s the proof:

The Caveats

Support is mostly fine, unless you worry about Safari 15.

Also, there is a difference between the values hidden and clip.

The hidden value does visually hide the overflow and will not add any visible scrollbars to the element. But! The hidden value does still technically allow you to scroll that element. You can force it sometimes with a mouse by highlighting text and dragging the direction of where the overflow is. And you can do it with JavaScript. The clip value does not allow you to do this. The content that is “clipped” away is truly inaccessible (visually).


Kilian Valkhof had a nice article about all this a while back, and also shows off the related overflow-clip-margin which is a nice bonus feature to clipping.

Wanna learn CSS from a course?

One response to “Single-Directionally Allowed Overflow”

  1. John says:

    It looks like the following combination does not work:

      overflow-y: clip;
      overflow-clip-margin: 56px;
    

    It needs to be overflow: clip exactly or it will be ignored. That’s a real shame. I’ve built carousels in the past where a box-shadow got cut off and I had to resort to paddings with equal amounts of negative margins to circumvent it, which leads to z-index issues and makes the code less readable.

Leave a Reply

Your email address will not be published. Required fields are marked *

Did you know?

Frontend Masters Donates to open source projects. $363,806 contributed to date.