overflow-x also hides overflow-y

Viewed 347

There are multiple questions named this way, but I didn't find one that applies to my case, so here I am:

In this snippet:

#container:hover {
  overflow-x: hidden;
}

#container {
  position: relative;
  width: 400px;
  height: 40px;
  background: red;
  margin: 2em;
}

#child {
  position: absolute;
  bottom: 0;
}
<div id="container">
  <div id="child">
    a<br/>
    b<br/>
    hover<br/>
    me
  </div>
</div>

You can see that overflow-x, which is applied when you hover the red box, will also hide the overflow-y (at least on Chrome). This is annoying because I have a tooltip that I would like to be able to overflow above the red box, and in the meantime I have a menu that will slide from the right side and that should stay hidden.

Is this a bug? Is there a workaround?

1 Answers

You can't change the way overflow-x and overflow-y behave (it's the same in Firefox and other browsers), but you can change the way your HTML is organized.

Put everything that you want to hide when overflowing in a single wrapper. Put your tooltip in another wrapper.

Something like this may suit your needs:

#container {
  position: relative;
  width: 400px;
  background: #f77;
  margin: 3em 2em;
}

#child {
  overflow: hidden;
  position: relative;
}

#menu {
  position: absolute;
  left: 100%;
  top: 0;
  background: #dd2;
  transition: .2s;
}

#child:hover #menu {
  transform: translateX(-100%);
}

#tooltip {
  position: absolute;
  bottom: 100%;
}
<div id="container">
  <div id="child">
    hover<br/>
    me
    <div id="menu">
      menu
    </div>
  </div>
  <div id="tooltip">
    a<br/>
    b
  </div>
</div>


Is the clipping behavior a bug?

No, the clipping is in accordance with the spec.

UAs must clip the scrollable overflow area of scroll containers on the block-start and inline-start sides of the box (thereby behaving as if they had no scrollable overflow on that side).

In your case, the "block-start" side is the top, and the "inline-start" side is the left. That's why you can put your tooltip below the content, and it will trigger a scrollbar.

#container:hover {
  overflow-x: hidden;
}

#container {
  position: relative;
  width: 400px;
  height: 40px;
  background: red;
  margin: 2em;
}

#child {
  position: absolute;
  /* bottom: 0; */
  top: 0;
}
<div id="container">
  <div id="child">
    hover<br/>
    me<br/>
    a<br/>
    b
  </div>
</div>

So why is it possible to scroll to content overflowing below the box, but not possible to simply make it visible? The reason is that when any overflow property is set to hidden, the entire box becomes a scroll container.

[A scroll container] allows the user to scroll clipped parts of its scrollable overflow area into view.

Related