为什么 overflow 与 z-index 交互?

Why is overflow interacting with z-index?

我想了解 z-index 背后的规则以及它如何与溢出交互 属性。

我有这个html:

<body>
  <div class="cell">
    Here is some text to keep things interesting
    <div class="boxy"></div>
  </div>
</body>

还有这个 css:

.boxy {
  position: absolute;
  z-index: 9999;
  top:70px;
  width: 50px;
  height: 50px;
  background: #0FF;
}

.cell {
  border: 2px solid #F00;
  position: relative;

  /* comment these two lines out and the box appears */
  /* or change them both to 'visible' */
  /* changing only one of them to 'visible' does not work */
  overflow-y: auto;
  overflow-x: auto;
}

我原以为青色框会出现,即使它超出 div.cell 的大小,因为它的 z-index 和位置已设置。

但是,使青色框出现的唯一方法是注释掉 overflow-x 和 -y 行。

我的问题是:如何让青色框出现在屏幕上,同时保持溢出为隐藏或自动?但更重要的是,我想了解 为什么 会发生这种情况。这里应用的 css 和布局规则是什么?

See my Plunkr. 这个例子当然是我实际使用的 HTML/CSS 的简化版本。


编辑 下面的答案似乎有些混乱,因为我解释得不够好。如果将两条溢出线注释掉,可以看到出现了青色框。它出现在 .cell 的边界之外。为什么会这样?如何让青色框出现,同时仍然隐藏溢出和 z-index?

绝对定位元素不会影响其父元素的尺寸。

因此,.cell DIV 没有影响其尺寸的内容,使其宽度为 100%,高度为 0 像素。

要显示该元素,您必须向 .cell 添加一个高度以包含 DIV,在本例中为 120 像素(顶部 70 像素 + 高度 50 像素)。

你的问题

当在 cell 节点上指定 overflow 时,您的问题与隐藏 boxycell 节点有关。

原因

背后的原因是 boxy 绝对位置对 cellheight 没有贡献,overflow 隐藏了它。

为什么显示没有溢出?

默认情况下 overflowvisible,对于浏览器来说这意味着 不要为溢出功能做任何特殊的事情 并且它不需要渲染溢出 = > 不隐藏 boxy.

Parent Class cell 需要设置它的高度。因为 absolute 元素的高度不影响它的父元素。

 .boxy {
      position: absolute;
      z-index: 9999;
      top:70px;
      width: 50px;
      height: 50px;
      background: #0FF;

    }

    .cell {
      border: 2px solid #F00;
      position: relative;

      /* comment these two lines out and the box appears */
      /* or change them both to 'visible' */
      /* changing only one of them to 'visible' does not work */
      overflow-y: auto;
      overflow-x: auto;
      min-height: 120px; /* height 70px(Top)+50px*/
    }

青色框仅在 overflow-xoverflow-y 可见时出现,否则消失的原因很简单,因为青色框溢出了单元格框。 overflow: visible 简单地表示 "paint this box even if it is overflowing its containing block" — 单元框是青色框的包含块,因为它的 position 是相对的。 overflow 的任何其他值都会导致溢出的内容从视图中被剪掉。这里没有什么特别的;特别是, z-index 是完全不相关的,并且没有问题标题所暗示的这种交互(并且真的没有理由将它设置为如此巨大的数字,除非您担心脚本将其他元素注入单元格)。

在单元格有 non-visible 溢出时允许出现青色框的唯一方法是从单元格中删除 position: relative 并将该声明应用于 parent单元格(在您的示例中,它是 body)。像这样:

body {
  position: relative;
}

.boxy {
  position: absolute;
  z-index: 9999;
  top: 70px;
  width: 50px;
  height: 50px;
  background: #0FF;
}

.cell {
  border: 2px solid #F00;
  overflow: auto;
}
<div class="cell">
  Here is some text to keep things interesting
  <div class="boxy"></div>
</div>

Z-indices 是 local 在它们的裁剪层级 parent 上下文中。这很non-intuitive。它们有自己的 z-stack 上下文,通常与外壳层次结构的上下文平行。但它们仍然会受到剪裁!如果您凭直觉期望 z-indices 是 absolute.

,那将是一个真正的痛苦

请注意,某些 jquery 容器(例如 accordion)悄悄指定 overflow: auto。即使它没有明确地出现在 你的 代码中。 (找到后可以在本地覆盖。)

另请注意,如果 overflow-x: visible 已设置,但 overflow-y 设置为 non-visible,则渲染引擎会悄悄地在内部将 overflow-x 更改为与 overflow-y 相同,供您娱乐。但是你已经发现了。

您可能应该能够通过在内部调用 transform: translate(0,0); [或任何所需的偏移量、% 或像素] 来规避不需要的非“可见”溢出裁剪,即使您的 z-index 很高您要悬浮的 div 的样式。 Transform 应该为该元素及其 children 创建一个新的本地 z-stack。这会让你绕过 overly-restrictive parent 或 grandparent.