【问题标题】:Why using absolute position causes the div to be on top?为什么使用绝对位置会导致 div 位于顶部?
【发布时间】:2020-06-18 18:20:30
【问题描述】:

请看这个非常简单的 sn-p 来说明我的问题:

#container {
  position: relative;
  padding: 20px;
  border: 2px solid gray;
}

#back {
  position: absolute;
  top: 0;
  bottom: 50%;
  left: 0;
  right: 0;
  background-color: #bbb;
}
<div class="col-sm-12" id="container">
  <div id="back"></div>
  <h1>Some Text</h1>
</div>

h1 标记位于 HTML 代码中的back 元素之后

由于我没有更改它的position 属性,所以它必须是static。 而且,据我所知,static 元素是根据页面的流向定位的。

那么……为什么绝对定位的div如上所示它的兄弟h1

我期待在h1 后面看到它,因为它排在第一位。

请注意,我知道如何纠正这种行为,我只是在问为什么!

更正的片段:

#container {
  position: relative;
  padding: 20px;
  border: 2px solid gray;
}

#back {
  position: absolute;
  top: 0;
  bottom: 50%;
  left: 0;
  right: 0;
  background-color: #bbb;
}

/* Adding the below corrects this behaviour */

h1 {
  position: relative;
}
<div class="col-sm-12" id="container">
  <div id="back"></div>
  <h1>Some Text</h1>
</div>

...为什么在h1 上使用position: relative 可以纠正这种行为?

【问题讨论】:

  • 当你绝对定位一个元素时,你将它从 DOM 流中移除。有一个有用的explanation here
  • @Lewis 这是否意味着在我的第二个 sn-p 中使用 position: relative 也会从流程中删除 h1
  • 没有。我不是 100% 确定机制,但我认为当你添加 position:relative 到一个元素时,它获得了沿着 z-index 移动的能力(尝试 z-indexing 一个没有位置的元素,它会做没有什么)。它使用默认值:auto 建立。在这个 SO 问题here 中有更多好的信息(具体看昆汀的回答)。
  • @Lewis 不,我正在谈论考虑所有元素的逻辑绘画顺序(如我的回答中所述),z-index 与这里无关......默认情况下它不会为 0但它是auto(可能相同但不完全相同)
  • @Lewis 仔细阅读第 8 步,您将看到 z-index 中 auto 和 0 之间的区别。 0 将创建一个堆叠上下文,但 auto 不会,这里有很大的不同;)

标签: html css css-position


【解决方案1】:

这就是绘画顺序的工作方式。如here 所述,您有以下顺序:

  1. 对于其所有 in-flow、非定位、块级树顺序的后代:如果元素是块、列表项或其他块 等效:

在此步骤中,您将打印h1 元素的背景和边框

  1. 否则:首先是元素,然后是所有它的流入、未定位、按树顺序排列的块级后代:

在这个复杂步骤中,您将打印h1元素的内容

  1. 所有定位、不透明或变换后代,按树形顺序归入以下类别:

    1. 所有使用“z-index: auto”定位的后代

在这一步中,您将打印定位元素#back;因此它将位于h1 的顶部,即使在 DOM 中它在之前。

换句话说,我们首先考虑流入元素,然后考虑定位元素。当然,更改z-index 和/或其他属性会影响顺序,因为可以考虑更多步骤。


例如将否定的z-index 添加到#back 将触发此规则:

  1. 由具有负 z 索引(不包括 0)按 z 索引顺序(最负值在前)的已定位后代形成的堆叠上下文 树顺序。

这将使#back 落后,因为h1 稍后会在步骤 (4) 和 (7) 中打印。


position:relative(或absolutefixed)添加到h1将使其成为定位元素,因此像#back它将触发(8),在这种情况下是树顺序 将决定。


您可能还注意到背景和内容都以 2 个不同的步骤打印,这也可能导致some non intuitive painting behavior

【讨论】:

  • 顺便说一句,我已经想到了你链接的问题......这太疯狂了。
【解决方案2】:

尝试关注。为h1添加样式如下

#container {
  position: relative;
  padding: 20px;
  border: 2px solid gray;
}

#back {
  position: absolute;
  top: 0;
  bottom: 50%;
  left: 0;
  right: 0;
  background-color: #bbb;
}
#container h1 {
  position : relative;
  z-index: 1;
}
<div class="col-sm-12" id="container">
  <div id="back"></div>
  <h1>Some Text</h1>
</div>

static elements 没有z-index,但是,其他default to 0 这就是为什么它停留在 html 的最底层并且非静态元素覆盖它。如果您希望在上面显示它们,请将静态元素的 position 设置为 relative 并提供任何 positive z-index value

【讨论】:

  • @TakitIsy - 更新答案
  • 不需要z-index,请参阅我的问题中的第二个 sn-p。
  • @TakitIsy - 如果元素具有相同的 z-index,则最后一个重叠。但是,如果您更改h1div#black 的顺序,那么您将需要z-index
【解决方案3】:

toprightbottomleftz-index 属性对 position: static 无效,这是元素的默认值,在您的情况下,h1 标签是。当 position 设置为 relative 时,当 z-index 的值不是 auto 时,它会创建一个新的堆叠上下文。

有关堆叠上下文的更多信息:

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context

【讨论】:

  • 我知道对位置没有影响:静态。请注意,我没有使用您在我的h1 中提到的任何属性。
  • 您的h1 元素默认为position: static,其中z-index 不起作用。当您将position: relative 用于h1 时,会创建一个新的堆栈上下文,其中设置了默认的z-index
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-06
  • 2017-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
  • 2018-01-10
相关资源
最近更新 更多