为什么内容没有被重叠元素的背景覆盖?

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没有任何复杂样式的样式(简单地是背景色)。我div通过应用负数使第二个与第一个重叠margin-top。我期望看到一个完全重叠,但事实并非如此。第二个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的背景传播,空白问题等等)。但是他们在某处有清楚的解释,我希望找到一个我可以清楚理解的官方资源,不仅会得到“可能是因为...”,“我怀疑这与...有关”,“它与...有关。”等


慕桂英4014372
浏览 549回答 3
3回答

噜噜哒

警告:阅读以下信息可能会影响您的心理健康。生成堆栈上下文的元素后代的绘制顺序为(请参阅z-index属性):如果元素是根元素:整个画布上元素的背景色。元素在整个画布上的背景图像,锚定在为根元素绘制时将使用的原点。如果元素是块,列表项或其他等效块:否则,如果元素是块级表:表格背景(先是颜色,然后是图像),除非它是根元素。列组背景(先是颜色,然后是图像)。列背景(先是颜色,然后是图像)。行组背景(先是颜色,然后是图像)。行背景(先是颜色,然后是图像)。单元格背景(先是颜色,然后是图像)。多列的单元格列规则。所有表格边框(以树顺序表示分隔的边框)。元素的背景色,除非它是根元素。元素的背景图片,除非它是根元素。元素的列规则。元素的边框。堆叠由具有负z索引(不包括0)的后代按z索引顺序(最负数先)然后按树顺序形成的上下文。对于其所有流入的,未定位的,块级的后代,按树顺序排列:如果元素是一个块,列表项或其他等效块:否则,该元素是一个表:表背景(先是颜色,然后是图像)。列组背景(先是颜色,然后是图像)。列背景(先是颜色,然后是图像)。行组背景(先是颜色,然后是图像)。行背景(先是颜色,然后是图像)。单元格背景(先是颜色,然后是图像)。单元格列规则(多列)。所有表格边框(以树顺序表示分隔的边框)。元素的背景色。元素的背景图像。元素的列规则。元素的边框。所有未定位的浮动后代,按树顺序。对于每个元素,都应将其视为已创建新的堆栈上下文,但是将所有实际创建新堆栈上下文的已定位后代和后代视为父级堆栈上下文的一部分,而不是此新堆栈上下文。如果该元素是生成堆栈上下文的内联元素,则:跳转到该行框中的元素的框(按树顺序)的7.2.1。对于元素所在的每个行框:否则:首先按元素顺序,然后按树顺序为其所有流入的,非定位的,块级后代:对于该元素的子级的每个框,在该行框中,按树顺序:注意,某些框可能是通过行拆分或Unicode双向算法生成的。原子替换的内容。对于每个元素,都应将其视为已创建新的堆栈上下文,但是将所有实际创建新堆栈上下文的已定位后代和后代视为父级堆栈上下文的一部分,而不是此新堆栈上下文。对于此行框中的所有流入,未定位的行内子级元素,以及此行框上的元素内的所有文本运行,按树顺序排列:任何影响元素文本的下划线(按应用该下划线的元素的树顺序排列)(以使最深元素的下划线(如果有的话)涂在最顶部,而根元素的下划线(如果有的话)涂在最底端)。任何影响元素文本的覆盖,都按照应用该覆盖的元素的树顺序排列(这样,最深元素的覆盖(如果有的话)被涂在最上面,根元素的覆盖(如果有的话)被涂在最底下)。文本任何影响元素文本的直通图,按应用直通图的元素的树顺序排列(这样,最深元素的直通图(如果有的话)涂在最上面,而根元素的直通图(如果有的话)为最底端绘制)。如果这是一段文字,则:否则,请跳至该元素的7.2.1元素的背景色。元素的背景图像。元素的列规则。元素的边框。对于内联元素:对于内联块和内联表元素:对于内联级替换元素:(可选)元素的轮廓(请参见下面的10)。如果该元素是块级替换的元素,则:原子替换的内容。否则,对于该元素的每个行框:(可选)如果元素是块级的,则元素的轮廓(请参见下面的10)。按树顺序排列的所有已定位,不透明或转换后代均属于以下类别:所有以“ z-index:auto”或“ z-index:0”排列的后代,按树顺序排列。对于具有“ z-index:auto”的元素,将其视为已创建新的堆栈上下文,但是任何定位的后代和实际创建新堆栈上下文的后代均应视为父级堆栈上下文的一部分,而不是此新堆栈上下文的一部分。 。对于“ z-index:0”的对象,将视为自动生成的堆栈上下文。所有不透明度小于1的不透明度子代,以树顺序创建原子生成的堆栈上下文。所有具有非变换以外的变换后代的所有后代,均以树顺序创建原子生成的堆栈上下文。堆叠上下文,这些上下文由定位的后代(z索引大于或等于1)按z索引顺序(最小的顺序为小)然后按树顺序形成。现在,请认真参考w3c油漆订购文档在第4.1点中,绘制了儿童的背景在第4.4点中,绘制了孩子的边框。完成第4点后,您的代码段的所有背景和边框均已绘制现在,在第7.2.1.5.1.1.3节中,绘制了孩子的文字。这是您看到的行为。还请注意,更改此行为很容易。我们可以激活点8.2(设置不透明度),它会像您期望的那样绘制:body {&nbsp; margin: 0;&nbsp; background: pink;&nbsp; color: #fff;}.box {&nbsp; margin-top: 20px;&nbsp; background: red;}.bottom {&nbsp; text-align: right;&nbsp; background: green;&nbsp; animation: animate 2s infinite alternate linear;&nbsp; opacity: 0.9999;}@keyframes animate {&nbsp; from {&nbsp; &nbsp; margin-top: 10px;&nbsp; }&nbsp; to {&nbsp; &nbsp; margin-top: -40px;&nbsp; }}<div class="box">&nbsp; some content</div><div class="bottom">&nbsp; other content</div>另一个片段,显示了文档中的几点:请注意,步骤4中的所有边框和背景在步骤3之后和setp 5之前呈现。但是步骤4中的文本是步骤7,因此在步骤5中的文本之后呈现。div {&nbsp; width: 200px;&nbsp; height: 100px;&nbsp; border: solid 10px;&nbsp; font-size: 40px;}.step3 {&nbsp; border-color: red;&nbsp; background-color: lightpink;&nbsp; z-index: -1;&nbsp; position: relative;&nbsp; margin-left: 10px;}.step41 {&nbsp; border-color: brown;&nbsp; background-color: yellow;&nbsp; margin-left: 30px;&nbsp; margin-top: -40px;}.step42 {&nbsp; border-color: blue;&nbsp; background-color: lightblue;&nbsp; margin-left: 50px;&nbsp; margin-top: -40px;&nbsp; color: red;}.step43 {&nbsp; border-color: green;&nbsp; background-color: lightgreen;&nbsp; margin-left: 160px;&nbsp; margin-top: -150px;&nbsp; color: crimson;}.step5 {&nbsp; float: left;&nbsp; background-color: white;&nbsp; margin-top: -30px;}div:hover {&nbsp; 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 {&nbsp; width: 100px;&nbsp; height: 1.3em;&nbsp; border: solid 12px tomato;&nbsp; font-size: 18px;}div:hover {&nbsp; position: relative;}<div>a long stretch of text overflowing to the other div</div><div></div>

斯蒂芬大帝

这是因为层次结构...我将尝试进一步解释它...body {&nbsp; margin: 0;&nbsp; background: pink;&nbsp; color: #fff;}.box {&nbsp; margin-top: 20px;&nbsp; background: red;}.bottom {&nbsp; margin-top:-10px;&nbsp; text-align: right;&nbsp; background: green;}<div class="box">&nbsp; some content</div><div class="bottom">&nbsp; other content</div>就像您的示例一样,我们的层次结构如下所示:.box&nbsp; &nbsp; .box content.bottom&nbsp; &nbsp; .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由于更大的垂直层次结构而将重叠
打开App,查看更多内容
随时随地看视频慕课网APP