【问题标题】:Why the content is not covered by the background of an overlapping element?为什么内容没有被重叠元素的背景覆盖?
【发布时间】:2018-07-21 17:11:09
【问题描述】:

情况如下:

body {
  margin: 0;
  background: pink;
  color: #fff;
}

.box {
  margin-top: 20px;
  background: red;
}

.bottom {
  text-align: right;
  background: green;
  animation: animate 2s infinite alternate linear;
}

@keyframes animate {
  from {
    margin-top: 10px;
  }
  to {
    margin-top: -40px;
  }
}
<div class="box">
  some content
</div>
<div class="bottom">
  other content
</div>

发生了什么?

如您所见,我们有两个div,没有任何复杂的样式(只是背景颜色)。我通过应用否定的margin-top 使第二个div 与第一个重叠。我希望看到一个完全重叠另一个,但事实并非如此。第二个div 在第一个的内容和背景之间滑动,这对我来说是一个奇怪的行为。

动画在这里无关,我只是用它来更好地展示行为。我们可以简单地在没有动画的情况下添加负边距,我们会得到同样的结果:

body {
  margin: 0;
  background: pink;
  color: #fff;
}

.box {
  margin-top: 20px;
  background: red;
}

.bottom {
  margin-top:-10px;
  text-align: right;
  background: green;
}
<div class="box">
  some content
</div>
<div class="bottom">
  other content
</div>

所以我的问题是:为什么会有这样的行为?


顺便说一句,我们都知道 CSS 有一些棘手的事情,当我们第一次面对它们时我们不会怀疑它们(比如边缘折叠、从正文到 html 的背景传播、空白问题等。 ..) 但它们在某处得到了清楚的解释,我希望找到一个官方资源,我可以清楚地理解这一点,而不仅仅是得到像 “也许这是因为......”“这样的东西我怀疑这与...”“我认为这与...有关”等。


我对此的看法/解释

我认为像文本这样的内容比背景和其他视觉样式更重要,所以当我们重叠时,我们将所有文本放在顶部,所有其他样式放在底部,我们决定每个组内的顺序,然后我们打印结果。

这是一个更复杂的例子:

body {
  margin: 0;
  background: pink;
  color: #fff;
}

div {
  font-size: 39px;
  line-height: 28px;
  margin-bottom: -20px;
  font-weight: bold;
}

body :nth-child(1) {
  background: red;
  border:3px solid brown;
}

body :nth-child(2) {
  background: blue;
  border:3px solid yellow;
  color: #000;
}

body :nth-child(3) {
  background: green;
  border:3px solid orange;
}
<div>
  some content
</div>
<div>
  other content
</div>
<div>
  more content
</div>

我们可以清楚的看到视觉栈如下(从下往上):

  • 第一个 div(背景+边框)的样式
  • 第二个 div(背景+边框)的样式
  • 第三个 div(背景+边框)的样式
  • 第一个 div的文本内容
  • 第二个 div的文本内容
  • 第三个 div的文本内容

重要通知:在回答之前,请注意,我不是在寻找解决此问题或如何避免此问题的方法。只需添加position:relative,行为就会消失,我们可以使用z-index 来决定堆叠。我希望了解为什么会发生这种情况。

【问题讨论】:

  • @Danield 啊!我很漂亮,有一个 dup :) [我在我的问题中也说过,但删除了通知,因为没有人出现你有点困惑......而且也没有明确的理由为什么它会像我们预期的那样而不是像我们预期的那样:/
  • 是的,这非常违反直觉......顺便说一句。即使基本问题相同,我也不会将您的问题称为重复问题,因为您也在问为什么规范也必须是这样的。我的问题的答案中也没有解释为什么。我很想看看有没有人能解释一下,谢谢! +1
  • 这种行为是否仅在您对属性使用负值时才会发生?还是正值也会发生这种情况?
  • @YvonneAburrow 好吧,这种行为发生在重叠时,所以我认为你不能使用边距的正值进行重叠......所以我在这里发现的唯一原因是使用负边距使它们重叠,但从理论上讲,如果也有一些正边距也会发生这种情况;)

标签: html css background overlap


【解决方案1】:

这个问题的答案远非每个人都在挖掘。因为我们都坚信这是一种利用用户体验的东西,一种直观的东西。有没有人认为这可以用于任何 CPU 处理优势?

浏览器渲染引擎不会完全绘制一个元素,然后继续绘制下一个,因为我们有 GPU 技术。渲染引擎将不同堆叠层中的元素一个接一个地绘制出来,然后将其移交给 GPU,然后 GPU 将所有层栅格化为显示在屏幕上的复合层。

那么,图层是如何创建的?

  • 渲染引擎在基础层上绘制所有背景和边框。
  • 为已指定定位的元素创建一个新层。该层堆叠在基础层上,以便 GPU 对其进行栅格化。当元素移动时,渲染引擎只告诉 GPU 移动层,其余的由 GPU 完成。从绘制开销中节省了 CPU。
  • 为指定了不透明度的元素创建一个新层。当不透明度发生变化时,GPU 会进行光栅化工作。
  • 类似地为输入、按钮、画布、视频创建一个新层,所有可能导致 CPU 重复绘制的东西都作为新层传输到 GPU。我们节省了大量的 CPU 处理,对吧? :)
  • 拒绝为具有负边距的元素创建任何新层:(。这很明显浏览器不能为每个具有边距的元素发布新层,它们有很多。即使它有负边距,它也可能重叠也可能不重叠其他元素。唯一可以确定的方法是查看渲染树。有什么意义?我们正在尝试节省处理,查看每个元素的渲染树会破坏它。
  • 为文本元素发布一个新层。 GPU 可以更有效地将文本光栅化到背景上,那么为什么要在基础层上使用 CPU 绘制它呢?这是最初的问题。我想现在每个人都可以回答了。

为什么文本要绘制在基础层之上的单独层上?

  • CPU 不需要在背景上绘制文本,CPU 很高兴。
  • 当文本颜色或阴影发生变化时,CPU 只绘制文本层,GPU 在背景上对其进行光栅化。
  • 当背景发生变化时,CPU 只绘制背景层,GPU 在其上光栅化文本。
  • 当文本在固定背景上滚动时,不需要绘画,CPU 只告诉 GPU 移动文本层,其余的由 GPU 完成。
  • 还有更多...

现在让我们来看看我们因此而遇到的魔法。

  • 案例 1: 当 position relative 添加到第二个 div 时,它会得到一个新层,这个新层堆叠在基础层上,甚至在第一个 div 的文本层上。
  • 案例 2: 应用不透明度时也会发生同样的情况。
  • 案例 3: 任何变换样式都会创建一个新图层。
  • 案例 4: 这个很有趣。边距不会为第二个 div 创建任何图层,它是在第一个 div 绘制后绘制在基础 div 上,因此它在同一层上绘制在第一个 div 上。第一个 div 上的文本位于它自己的层上,该层堆叠在基础层之上,因此 GPU 将文本栅格化到第二个 div 的背景上。

[来源:developers.google.com]

【讨论】:

  • 很明显,您已经完成了一项伟大的工作。但是,很抱歉这么说,我不认为你的结论是准确的。解释为什么我不同意这一点会太长,而且主要是基于意见,所以我认为这样做不值得....无论如何,我会为您的回答所做的工作量投票显示。
  • 仅仅指出反对的结论将有助于进一步的研究:)
  • 来源(在您的回答中)是否解释了您所解释的内容?我认为不是,但可能是我,忽略了它。感谢您如此清晰地解释 CPU 和 GPU 交互的努力。非常感谢!
【解决方案2】:

警告:阅读以下信息可能会影响您的心理健康。

生成堆叠上下文的元素的后代的绘制顺序(参见 z-index 属性)是:

  1. 如果元素是根元素:
    1. 整个画布上元素的背景颜色。
    2. 元素的背景图像,位于整个画布上,锚定在为根元素绘制时将使用的原点。
  2. 如果元素是
    • 块、列表项或其他块等效项:
      1. 元素的背景颜色,除非它是根元素。
      2. 元素的背景图片,除非它是根元素。
      3. 元素的列规则。
      4. 元素的边框。
    • 否则,如果元素是块级表:
      1. 表格背景(颜色然后图像),除非它是根元素。
      2. 列组背景(颜色然后图像)。
      3. 列背景(颜色然后图像)。
      4. 行组背景(颜色然后图像)。
      5. 行背景(颜色然后图像)。
      6. 单元格背景(颜色然后图像)。
      7. 多列的单元格列规则。
      8. 所有表格边框(按树形顺序分隔边框)。
  3. 由具有负 z 索引(不包括 0)按 z 索引顺序(最负值在前)定位的后代形成的堆叠上下文 树顺序。
  4. 对于所有流入的、非定位的、块级的树顺序后代:
    • 如果元素是块、列表项或其他等效块:
      1. 元素的背景颜色。
      2. 元素的背景图片。
      3. 元素的列规则。
      4. 元素的边框。
    • 否则,该元素是一个表格:
      1. 表格背景(颜色然后图像)。
      2. 列组背景(颜色然后图像)。
      3. 列背景(颜色然后图像)。
      4. 行组背景(颜色然后图像)。
      5. 行背景(颜色然后图像)。
      6. 单元格背景(颜色然后图像)。
      7. 单元格列规则(多列)。
      8. 所有表格边框(按树形顺序分隔边框)。
  5. 所有未定位的浮动后代,按树顺序排列。对于其中的每一个,将元素视为创建了一个新的堆叠 上下文,但任何定位的后代和实际上 创建一个新的堆叠上下文被认为是父级的一部分 堆叠上下文,而不是这个新的。
  6. 如果元素是生成堆叠上下文的内联元素,则:
    1. 对于元素所在的每个行框:
      1. 跳至 7.2.1 以获取该行框中元素的框(按树顺序)。
  7. 否则:首先是元素,然后是其所有流入的、非定位的、块级的后代(按树顺序):

    1. 如果元素是块级替换元素,则:被替换的内容,原子地。
    2. 否则,对于该元素的每个行框:

      1. 对于作为该元素的子元素的每个框,在该行框中,按树顺序:

        1. 元素的背景颜色。
        2. 元素的背景图片。
        3. 元素的列规则。
        4. 元素的边框。
        5. 对于内联元素:
          1. 对于此行框中的所有流入、非定位、行内级子元素,以及行内的所有文本行 此行框中的元素,按树顺序:
            1. 如果这是一段文本,则:
              1. 任何影响元素文本的下划线,按照应用下划线的元素的树顺序(这样最深 元素的下划线,如果有的话,画在最上面,根 元素的下划线(如果有的话)绘制在最底部)。
              2. 任何影响元素文本的上划线,按照应用上划线的元素的树顺序(这样最深 元素的上划线,如果有的话,画在最上面,根 元素的上划线(如果有的话)绘制在最底部)。
              3. 正文
              4. 影响元素文本的任何换行,按应用换行的元素的树顺序(这样最深 元素的 line-through,如果有的话,被画在最上面,根 元素的贯穿线(如果有的话)绘制在最底部)。
            2. 否则,针对该元素跳转到 7.2.1
        6. 对于 inline-block 和 inline-table 元素:
          1. 对于其中的每一个,将元素视为创建了一个新的堆叠上下文,但任何定位的后代和后代 实际上创建一个新的堆叠上下文被认为是 父堆叠上下文,而不是这个新的。
        7. 对于内联级替换元素:
          1. 以原子方式替换的内容。
        8. (可选)元素的轮廓(参见下面的 10)。

        请注意,某些框可能是通过行拆分或 Unicode 双向算法生成的。

    3. (可选)如果元素是块级元素,则元素的轮廓(参见下面的 10)。

  8. 所有已定位、不透明或变换的后代,按树形顺序分为以下几类:

    1. 所有具有“z-index:auto”或“z-index:0”的定位后代,按树顺序排列。对于那些带有'z-index:auto'的元素,将元素视为 它创建了一个新的堆叠上下文,但是任何定位的后代和 实际创建新堆叠上下文的后代应该是 被认为是父堆叠上下文的一部分,而不是这个新的。为了 带有'z-index:0'的那些处理生成的堆叠上下文 原子地。

    2. 所有 opacity 小于 1 的 opacity 后代,按树形顺序创建一个原子生成的堆叠上下文。

    3. 所有具有非无变换的变换后代,按树顺序,创建原子生成的堆叠上下文。
  9. 由 z 索引大于或等于 1 的已定位后代形成的堆叠上下文按 z 索引顺序(最小的在前)然后是树 订购。

现在认真,参考the w3c paint order documentation

在第4.1点中,儿童的背景被绘制

在第 4.4 点中,孩子的边框被绘制。

当第 4 点完成后,sn-p 的所有背景和边框都已绘制完毕

现在,在第 7.2.1.5.1.1.3 点,孩子们的文字被绘制。

这是您看到的行为。

另请注意,更改此行为很容易。我们可以激活第 8.2 点(设置不透明度),它会按照您的预期进行绘制:

body {
  margin: 0;
  background: pink;
  color: #fff;
}

.box {
  margin-top: 20px;
  background: red;
}

.bottom {
  text-align: right;
  background: green;
  animation: animate 2s infinite alternate linear;
  opacity: 0.9999;
}

@keyframes animate {
  from {
    margin-top: 10px;
  }
  to {
    margin-top: -40px;
  }
}
<div class="box">
  some content
</div>
<div class="bottom">
  other content
</div>

另一个sn-p,显示文档中的几个点:

注意,步骤4中的所有边框和背景都是在步骤3之后,setp 5之前渲染的。但是步骤4中的文本是步骤7,所以是在步骤5中的文本之后渲染的

div {
  width: 200px;
  height: 100px;
  border: solid 10px;
  font-size: 40px;
}

.step3 {
  border-color: red;
  background-color: lightpink;
  z-index: -1;
  position: relative;
  margin-left: 10px;
}

.step41 {
  border-color: brown;
  background-color: yellow;
  margin-left: 30px;
  margin-top: -40px;
}

.step42 {
  border-color: blue;
  background-color: lightblue;
  margin-left: 50px;
  margin-top: -40px;
  color: red;
}

.step43 {
  border-color: green;
  background-color: lightgreen;
  margin-left: 160px;
  margin-top: -150px;
  color: crimson;
}

.step5 {
  float: left;
  background-color: white;
  margin-top: -30px;
}

div:hover {
  position: relative;
}
<div class="step3">Step 3 negative zindex</div>
<div class="step41">step4 In flow, number 1</div>
<div class="step42">In flow, number 2</div>
<div class="step43">In flow, number 3</div>
<div class="step5">step 5 float</div>

我不知道这是否算作一个用例:这更自然的初始行为是由元素定位相对设置的行为

div {
  width: 100px;
  height: 1.3em;
  border: solid 12px tomato;
  font-size: 18px;
}

div:hover {
  position: relative;
}
<div>a long stretch of text overflowing to the other div</div>
<div></div>

【讨论】:

  • 心理健康受到影响:/ .. 老实说,我看到了这个链接,但没想到最后会读它......你还必须阅读很多时间才能获得绘画的循环,好吧不是超级简单......谢谢你;)......是的,关于不透明度,我注意到了它,我也注意到了所有创建新堆叠上下文的属性,如转换等
  • 好的,所以所有这一切的主要关键字是 [For all 它的流入 ...] 在 4.1 中,当第一次阅读时我明白,对于我们所做的每个孩子所有的循环,但事实并非如此......顺便说一句,我知道这是规范,但一个想法为什么这个决定?我也知道我提供的示例是一个糟糕的代码,所以理论上很难出现这种情况,因此我们不能抱怨绘画过程
  • 是的,请注意,这是一个非常有限的情况:流入,未定位,未转换,未浮动,没有不透明度......我相信这是为了提供您想要的特殊情况一种 flat 显示,其中几个框形成背景,文本覆盖所有内容。但这只是我的猜测
  • 我添加了一个 sn-p 显示(或至少试图显示)绘制顺序中的不同步骤,特别是 3、4、5 和 7 的一部分
  • 谢谢 :) 我也在玩一些东西,以触发其他一些步骤,看看我是否发现了其他一些 strange 行为 :) ...正如你所说的那样,我们最终将使用非常特殊的案例,我们可能永远不会使用......所以现在我试图找到是否有可能有一个真正的用例,我们可以看到这个并确认它应该是这样的.
【解决方案3】:

@vals 的答案突出显示了规范中解释此行为的位置,但仅提供了 80% 的答案,因为我仍在寻找 为什么?。由于这种行为在某种程度上是违反直觉的,因此我试图找到真实的用例,在这些用例中,这种行为应该是那样的,而不是我预期的那样。

在进行了大量搜索之后,我得出了一个合乎逻辑的结论,即优秀的 Web 开发人员应该了解规范中指定的任何内容,并且不应该为随机/意外行为留有余地,尤其是当涉及到由规范而不是浏览器特定解释的行为时。

所以我们编写代码,我们面对奇怪的事情,我们了解它们,我们调整我们的代码......我们这样做直到我们有一些按预期工作的东西。


由于网络开发人员可以完全控制他的开发,我问自己是否有任何外部工具可能会影响他的 CSS 和他无法控制的网页呈现?

是的,其中之一与可访问性有关。我不是在谈论 Web 开发人员应遵循的准则,而是在谈论某些网站中的一些小部件,这些小部件允许您增加字体大小、更改对比等,以帮助您更好地阅读内容。这种小部件可以使用附加组件集成到任何地方。

这是一个简化的例子,用户可以增加字体大小,上述行为很有用,因为它将保留文本内容,因此我们可以轻松阅读:

$('button').click(function() {
   $('body').css('font-size','22px');
})
body {
 font-size:14px;
 max-width:500px;
}
section {
  height: 80px;
  background: red;
  padding:5px;
  border-top: 40px solid blue;
  color:#fff;
}
div {
  height:80px;
  background:url(https://lorempixel.com/g/400/400/) center/cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Make font bigger</button>
<section>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam cursus posuere dolor vel faucibus. Proin augue orci, tempor cursus erat aliquet, pellentesque suscipit odio. Sed eleifend diam in justo vehicula feugiat. In pretium, elit eu dapibus efficitur,
</section>
<section>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam cursus posuere dolor vel faucibus. Proin augue orci, tempor cursus erat aliquet, pellentesque suscipit odio. Sed eleifend diam in justo vehicula feugiat. In pretium, elit eu dapibus efficitur,
</section>
<div>
</div>

在此代码中,开发人员使用了等于14px 的字体大小,这对于某些人来说可能难以阅读,因此我们想要增加它是合乎逻辑的。如果我们这样做,我们将有 strange 行为,但如果不是这样,内容将被隐藏,因此我们无法再阅读它!

这种情况为做出这样的决定提供了充分的理由,正如我在问题中所说:在这种情况下,内容比背后的样式更重要,尤其是在涉及改变初始行为的外部工具时。

这里增加 font-size 的目的是突出内容,而不是确认绘画顺序应该是这样的背景或边框以满足此要求。

【讨论】:

  • 有趣的一点......是的,可能就是这个原因。但是,当然,很难确定。除非你当时碰巧和 w3c 小组的人交谈。
  • @vals 是的,但我至少发现了一个真实案例,如果内容被隐藏,我会感到惊讶;)
  • @vals,所以开发者必须足够笨,才能为部分设置固定的 80px 高度,并且足够聪明,在部分之间留出 40px 的边距,这样溢出的文本就可以显示而无需移至下一部分,我想知道他们中有多少人最终会这样做。如果没有边距,以后绘制文本会有用吗?我认为规范甚至没有考虑这些罕见的情况来促进。此外,开发人员不应为随机/意外行为留有余地,尤其是在涉及常见/通用行为而非浏览器特定行为时
  • @MunimMunna 好吧,我认为 Temani 的重点更多是关于您始终为使页面看起来整洁而留下的通常边距,而不是您在考虑这种情况时留下的边距。但是,正如我之前所说,了解 w3c 在编写标准时的真正想法主要是基于意见,并且难以证明。
  • @vals 是的,它是基于意见的,但我是说,如果没有边距,那么稍后再绘制文本不会有任何好处。 w3c 编写规范不太可能促进这种极其罕见的情况,即稍后可以很好地绘制文本。但谁知道呢!
【解决方案4】:

提出这个问题的一种方法是:是否可以以不同的方式处理它并仍然管理 CSS 所需的不同功能,尤其是 float 属性?

规范说的是,对于堆叠上下文(基本上是定位的 DOM 树的一部分的顶部块),您按该顺序绘制元素:

  1. 堆叠上下文顶部元素的背景
  2. z-index 为负数的元素

直到现在才有意义,那么你有

  1. 所有块级元素的所有背景和边框 (基本上是 display: block 但未定位的元素)在顶部元素下的树中。
  2. 然后是顶部元素下所有树的所有浮动元素。
  3. 此步骤从步骤 2 开始,因此它不会真正干扰此特定情况。
  4. 然后是所有顶部元素下的所有树的所有流入元素(或非浮动元素)(不仅仅是在7中呈现的文本,它都是内联元素。如果你的内联元素有背景,它会掩盖背后的东西)。

这样做的“问题”是流入元素没有按树的顺序呈现。树中较低的元素的背景可以在树中的流入元素之前呈现。问题中暗示的是,我们有点期待类似的东西:

  1. 按树形顺序渲染所有块级元素的所有背景、边框和流入元素。

这将以更直观的方式生成元素。那么,为什么还要将流入元素与其他元素分开。为什么步骤 5 在步骤 7 之前?很明显,如果你这样做,那么你的浮动元素就会出现问题。它们必须放在流程的其余部分之前,因为它们就是这样,从流程中取出的元素。所以第5步是有道理的,你需要在非浮动元素之前考虑浮动元素。

如果它们在第 4 步中被渲染,像这样:

  1. 所有背景和边框,然后是浮动元素,然后是树形顺序中所有块级元素的非浮动元素。

由于浮动元素的预期,您仍然有问题。看到这个sn-p:

body {
  margin: 0;
  background: pink;
  color: #fff;
}

.box {
  margin-top: 20px;
  background: red;
}

.bottom {
  margin-top:-10px;
  text-align: left;
  background: green;
  
}
<div class="box">
  <span>some content some content some content some content some content some content some content some content some content some content</span>
<span style="float: left; background: navy">
  floated content box<br>
  floated content box<br>
  floated content box<br>
  floated content box
  </span>
  
 
  
  
</div>
<div class="bottom">
  <span style="background-color:turquoise;">other content</span>
  <span style="float: left; background-color:bisque;">
  floated content bottom<br>
  floated content bottom<br>
  floated content bottom
  </span>
  
 
  
</div>

您会看到浮动元素对块元素的高度没有任何影响,这是预期的,否则结果会很奇怪,根本不是浮动元素的预期。因此,如果上部块中的浮动元素在下部元素的背景之前渲染,那么背景将在浮动元素之上。所以渲染背景,然后浮动,然后按树顺序流入也不起作用。在进入正常流程之前,您需要放置所有树的所有浮动元素。

因此,您几乎被这种处理渲染的方式所困扰,这意味着您必须在一个上下文中检查所有元素以定位浮动元素,然后定位正常流程的其余部分。它有这种奇怪的副作用,但考虑到 CSS 规范所期望的不同定位的复杂性,我不确定还有其他方法可以做到这一点。

编辑:

我认为规范中明确规定了这种行为,请参见此处: https://www.w3.org/TR/CSS2/visuren.html#floats

float 的内容被堆叠起来,就像 float 生成了新的堆叠一样 上下文,除了任何定位元素和元素 实际上创建新的堆叠上下文参与浮动的父级 堆叠上下文。浮动可以与正常流程中的其他框重叠 (例如,当浮动旁边的正常流框具有负边距时)。 发生这种情况时,浮动将呈现在非定位的前面 流入块,但在流入内联之后。

这正是我所说明的,这意味着浮动元素应该与流入块重叠,并在这样的背景前呈现。

【讨论】:

  • 好点,但我只同意 50% :) 因为这里的浮动问题是溢出,所以如果规范就像我想要的那样,它将被底部元素隐藏,我会在首先是合乎逻辑的,因为我们遇到了溢出问题,我们需要通过正确清除浮动来修复它。我同意 50%,因为你的答案与我的结论几乎相同。在这里,您隐含地得出结论,我们可能会面临溢出(通过浮动或文本变大),并且在背景上方显示内容比相反更重要。
  • 你的答案和我的 (stackoverflow.com/a/48895817/8620333) 之间的区别在于,这样的东西在开发阶段是可见的,所以如果规范是我想要的并且浮动是隐藏的,我们可以看到这个并且通过进行必要的更改来更正代码,这就是为什么我不 100% 同意您的观点,因为开发人员应该了解结果并进行调整。但在我的回答中,我们可能会面临 CSS 将在客户端更改以创建溢出的情况;因此,我们应该优先考虑内容。当然,这只是个人结论:)
  • @TemaniAfif 查看我的编辑,我认为这种行为在 CSS 规范中显然是预期的,这是预期的行为,所以在我看来渲染指南是唯一的方法(或者至少是最直接的方式)来实现规范。但是,是的,所有这些都是猜测,可能还有更多。这只是尝试理解这种行为的不同方法。
  • 是的,我知道这在规范中很明显 :) 并且我也说过:我们面临 我们 没有预料到的事情,然后我们在规范中阅读了它们这给了你正确的预期方式。当我阅读规范时,我很清楚这一点,但我真正的问题是他们为什么会这样决定?所以是的,规范中对事情进行了很好的解释,所有这些行为都是合乎逻辑和正常的,但有时我们可能会问“他们为什么决定这样做?” “他们的理由是什么?”。
【解决方案5】:

发生的情况是,您有 2 个重叠的“框”需要在同一个 z 层第 0 层上渲染。但是,在 Introduction to the CSS basic box model 中,解释了 边界区域,它说:

当在盒子上设置了背景(background-colorbackground-image)时,它会延伸到边框的外边缘(即在 z 排序中延伸到边框下方)。

我假设边框和内容都在“前景”中。

所以,在同一层上绘制所有框的规范,结合在前景下绘制背景的规范,我猜它导致在all下绘制all背景前景。

在每个“子层”内,重叠是根据 HTML 顺序。

要了解为什么帖子中的 DIV 在同一层,请阅读The stacking context

要“理解”为什么背景会出现在前景之下,应该阅读Introduction to the CSS basic box model

【讨论】:

  • 我对每一个都进行了尝试,但它们似乎没有朝着正确的方向发展。我需要了解发生了什么,所以大多数阅读都在 MDN 上。一旦我明白这 3 个 DIV 需要在同一层上,我就明白帖子中发生了什么。
  • 要了解为什么 3 个 DIV 在同一层,请阅读The stacking context
  • 首先只有 2 个 Div,第一个答案已经提供了所有详细信息,所以不确定你是否阅读过它并阅读另一个。主要问题是“为什么?”这种行为,我们已经有了解释
【解决方案6】:

重要的是要注意,对于这种情况,每个 div 都有其高度,因为它的内容。 假设结果高度为 20px。

那么,如果你说第一个div会有margin-top: 20px,那么在第一个div之后声明的第二个div从第一个div结束的地方开始。

所以,第二个的初始位置将是第一个的边缘顶部加上第一个的高度。假设这给出了 40 像素。

所以,在这种情况下,第二个的起始位置是 40px。当您说第二个 div 的 margin-top 为 -15px 时,初始位置将为 40px-15px。 因此,如果您希望第二个与第一个重叠,则应将 margin-top 设置为等于第一个高度的负数。

【讨论】:

  • 你明白问题是什么了吗?
  • 哇.. 实际上是的,但是您清楚地说您不是在寻找像 position: relative 这样的答案,这就是您在那里看到的行为。澄清:所有元素都有默认值的css属性。你知道的,对吧?属性位置,默认值为静态。这就是你在那里看到的。你可以阅读一些关于它的内容。因此,如果您希望元素相对于另一个元素采取相对位置,请使用相对位置。请在这里阅读一下:link
  • 好吧,所以你没有理解这个问题:) ...我知道关于位置和所有不同值的一切,我知道如何使用相对和所有东西,我非常了解 CSS ;) ....但清楚地阅读了这个问题,我希望了解我看到的行为是在哪里指定的[并且 vals 的答案回答了这个] 然后我正在寻找为什么这种行为的决定......请仔细阅读这个问题, cmets和所有回答前回答
【解决方案7】:

这是因为等级制度……我会试着解释一下……

body {
  margin: 0;
  background: pink;
  color: #fff;
}

.box {
  margin-top: 20px;
  background: red;
}

.bottom {
  margin-top:-10px;
  text-align: right;
  background: green;
}
<div class="box">
  some content
</div>
<div class="bottom">
  other content
</div>

就像你的例子一样,我们的层次结构看起来像:

.box
    .box content
.bottom
    .bottom content

所以,现在如果你不通过position: relative,那么它将使用普通的 HTML 层次结构而不检查 div...

您在.box.bottom 实现了背景,所以在这种情况下,当您将margin-top 添加到.bottom 时,那么:

  • .bottom.box 具有相同的水平层次位置,但 .bottom 具有更大的垂直,因此将重叠 .box 背景
  • .bottom content.box content 的位置比 .bottom.box 大,所以它们会重叠
  • .bottom content 将重叠 .box content 因为更大的垂直层次结构

【讨论】:

  • 是的,这就是我在 我的意见部分 中所理解的 :) 但是我在哪里可以阅读到这个?官方规范的任何链接
  • 我认为你不会找到最好的官方规范,因为这是 HTML 层次结构的结果......你只能读到这样的东西:webreference.com/html/rendering/2.html
  • 这就是我问的原因:) 因为如果我们简单地阅读层次结构,我们将了解元素在每个 othet 等内部的情况,因此我们将了解样式是如何应用的......但在这种情况下,我们可以认为这两个元素都是独立的,不能像这样折叠。所以当我们看到这种行为时我们可以找到解释,但我们应该能够找到解释这种行为会发生的东西
  • 就像margin-collpasing ..你面对他们,有一天有人告诉你它发生了,你可以使用..但是在规范中你可以找到关于它何时以及如何发生的清晰描述以及所有不同的情况
  • 是的...我没想到...从来没有! :D 我会搜索,但如果你能找到一些东西,请分享你的答案 :) 我也会这样做 ;) 很好的问题 :D
猜你喜欢
  • 1970-01-01
  • 2021-06-07
  • 2022-01-05
  • 1970-01-01
  • 2013-06-06
  • 2012-08-07
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
相关资源
最近更新 更多