【问题标题】:Why is overflow interacting with z-index?为什么溢出与 z-index 交互?
【发布时间】:2016-06-20 03:38:59
【问题描述】:

我正在尝试了解 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 和位置已设置。

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

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

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


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

【问题讨论】:

  • 删除位置
  • 哪个职位?为什么会这样?这里有什么规则?

标签: css overflow z-index


【解决方案1】:

青色框仅在overflow-xoverflow-y 可见时出现,否则消失的原因仅仅是因为青色框溢出了单元格框。 overflow: visible 仅仅意味着“绘制这个盒子,即使它溢出了它的包含块”——单元格框是青色盒子的包含块,因为它的position 是相对的。 overflow 的任何其他值都会导致溢出的内容从视图中被剪掉。这里没有什么特别的。特别是,z-index 是完全不相关的,并且没有问题标题所暗示的这种交互(并且真的没有理由将其设置为如此巨大的数字,除非您担心脚本会将其他元素注入单元格)。

在单元格有不可见溢出时允许出现青色框的唯一方法是从单元格中删除 position: relative 并将该声明应用于单元格的父级(在您的示例中,它是主体) .像这样:

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>

【讨论】:

  • 好的。我想我现在明白了。 overflow 控制元素可见边界之外的 DOM 内容会发生什么。 z-index 与可见元素的堆叠有关。所以,如果一个元素是不可见的,它就不能被堆叠。感谢您的澄清。 ps- 在实际应用中,我对 z-index 使用更合理的值。 9999 只是为了(对我自己)证明问题不在于 z-index 太低。
  • @Andrew Eisenberg:元素仍然可以堆叠 - 当溢出不可见时你看不到它。这就是布局不受滚动影响的原因。
  • 不幸的是,这意味着我的方法将不起作用,因为它依赖于 .boxy 相对于 .cell 的位置。通过将position: relative 放在DOM 上方,我需要使用JS 计算每个.boxy 元素的正确定位。
  • @AndrewEisenberg 嗨,安德鲁,我遇到了同样的问题。只是想知道你是如何解决的。
  • 最后,我不得不重新架构这部分 dom。我一直在尝试使用本地定义的 dom 元素来实现弹出窗口。更改是创建一个从根悬挂下来的单个弹出 dom 元素,该元素显示、隐藏和移动基于鼠标与本地 dom 元素的交互。我对这个解决方案不是 100% 满意,因为卷轴很笨拙,但比以前好多了。
【解决方案2】:

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

因此,.cell DIV 没有影响其尺寸的内容,使其 100% 宽 x 0px 高。

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

【讨论】:

  • 我了解关于 .cell 没有尺寸的部分。我对问题做了些许改动,以便父 div 中有文本。但我不想让.cell 有高度。我将元素添加到 z-index 因为我希望它浮动在其他元素之上。我的目标是创建一个随其指向的元素一起移动的粘性工具提示。
  • 啊,我现在更明白你的问题了。很有趣。
  • 确实很有趣。 :) 我只是希望我错过了一件愚蠢的小事。
【解决方案3】:

父类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*/
    }

【讨论】:

  • 这不是我想要的。我不希望.cell 根据.boxy 改变它的高度。可以看到,如果去掉overflow这两条线,就会出现这个框,而且是在.cell的位置之外。
【解决方案4】:

您的问题

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

原因

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

为什么显示时没有溢出?

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

【讨论】:

  • 添加高度和宽度会使.cell 更大,但这不是我想要的。我希望.boxy 浮动在.cell 之外的所有其他元素之上。
  • @AndrewEisenberg 然后只需使用relative 而不是absolute,看看更新版本。
  • 并非如此。这仅在您将框移动到单元格本身的坐标时才有效。我希望该框即使在.cell 的边界之外也是可见的。当您注释掉溢出时会发生这种情况。
  • @AndrewEisenberg 对于这种情况,您必须编写一些 javascript,因为.boxy 不能在没有绝对定位的情况下在外面,并且不能用它来增加高度。相对好的选择是绝对定位.boxy,并在其中使用javascript设置height of .cell
  • 为什么在没有溢出集的情况下会起作用?在这种情况下,我不需要设置.cell 的高度。
【解决方案5】:

Z 索引是 local 在其剪切层次父上下文中的。这是非常不直观的。它们有自己的 z 堆栈上下文,通常与外壳层次结构平行。但它们仍然会受到剪裁!如果您直观地期望 z 索引是绝对的,这可能是一个真正的痛苦。

请注意,一些 jquery 容器,例如手风琴,会悄悄地指定溢出:自动。即使它没有在 你的 代码中明确显示。 (找到后可以在本地覆盖。)

还要注意,如果设置了overflow-x:visible,但是overflow-y 设置为不可见,那么渲染引擎会悄悄地在内部将overflow-x 更改为与overflow-y 相同以供您娱乐。但你已经发现了。

您可能应该能够通过在 div 样式中调用 transform: translate(0,0); [或任何所需的偏移量、% 或像素] 来规避不需要的非“可见”溢出剪辑,即使您的 z-index 很高。你想悬浮。 Transform 应该为该元素及其子元素创建一个新的本地 z 堆栈。这会让你绕过一个过于严格的父母或祖父母。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 2012-12-29
    • 2019-07-13
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多