html – 元素重叠时背景的奇怪行为

前端之家收集整理的这篇文章主要介绍了html – 元素重叠时背景的奇怪行为前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是情况(使用Chrome,Firefox和IE11测试的代码)
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与第一个div重叠。我期待看到一个完全重叠另一个,但事实并非如此。第二个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的文本内容

重要提示:在回答之前,请注意我不是要找到解决方法或如何避免这种情况。通过简单地添加位置:相对行为消失,我们可以使用z-index来决定堆叠。我希望了解为什么会发生这样的事情。

解决方法

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

The painting order for the descendants of an element generating a stacking context (see the z-index property) is:

  1. If the element is a root element:
    1. background color of element over the entire canvas.
    2. background image of element,over the entire canvas,anchored at the origin that would be used if it was painted for the root element.
  2. If the element is
    • a block,list-item,or other block equivalent:
      1. background color of element unless it is the root element.
      2. background image of element unless it is the root element.
      3. column rule of the element.
      4. border of element.
    • Otherwise,if the element is a block-level table:
      1. table backgrounds (color then image) unless it is the root element.
      2. column group backgrounds (color then image).
      3. column backgrounds (color then image).
      4. row group backgrounds (color then image).
      5. row backgrounds (color then image).
      6. cell backgrounds (color then image).
      7. cell column rule for multi-column.
      8. all table borders (in tree order for separated borders).
  3. Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then
    tree order.
  4. For all its in-flow,non-positioned,block-level descendants in tree order:
    • If the element is a block,or other block equivalent:
      1. background color of element.
      2. background image of element.
      3. column rule of the element.
      4. border of element.
    • Otherwise,the element is a table:
      1. table backgrounds (color then image).
      2. column group backgrounds (color then image).
      3. column backgrounds (color then image).
      4. row group backgrounds (color then image).
      5. row backgrounds (color then image).
      6. cell backgrounds (color then image).
      7. cell column rule (multi-column).
      8. all table borders (in tree order for separated borders).
  5. All non-positioned floating descendants,in tree order. For each one of these,treat the element as if it created a new stacking
    context,but any positioned descendants and descendants which actually
    create a new stacking context are considered part of the parent
    stacking context,not this new one.
  6. If the element is an inline element that generates a stacking context,then:
    1. For each line Box that the element is in:
      1. Jump to 7.2.1 for the Box(es) of the element in that line Box (in tree order).
  7. Otherwise: first for the element,then for all its in-flow,block-level descendants in tree order:

    1. If the element is a block-level replaced element,then: the replaced content,atomically.
    2. Otherwise,for each line Box of that element:

      1. For each Box that is a child of that element,in that line Box,in tree order:

        1. background color of element.
        2. background image of element.
        3. column rule of the element.
        4. border of element.
        5. For inline elements:
          1. For all the elements in-flow,inline-level children that are in this line Box,and all runs of text inside the
            element that is on this line Box,in tree order:
            1. If this is a run of text,then:
              1. any underlining affecting the text of the element,in tree order of the elements applying the underlining (such that the deepest
                element’s underlining,if any,is painted topmost and the root
                element’s underlining,is drawn bottommost).
              2. any overlining affecting the text of the element,in tree order of the elements applying the overlining (such that the deepest
                element’s overlining,is painted topmost and the root
                element’s overlining,is drawn bottommost).
              3. the text
              4. any line-through affecting the text of the element,in tree order of the elements applying the line-through (such that the deepest
                element’s line-through,is painted topmost and the root
                element’s line-through,is drawn bottommost).
            2. Otherwise,jump to 7.2.1 for that element
        6. For inline-block and inline-table elements:
          1. For each one of these,treat the element as if it created a new stacking context,but any positioned descendants and descendants
            which actually create a new stacking context are considered part of
            the parent stacking context,not this new one.
        7. For inline-level replaced elements:
          1. the replaced content,atomically.
        8. Optionally,the outline of the element (see 10 below).

        Note,some of the Boxes may have been generated by line splitting or the Unicode bidirectional algorithm.


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

        >所有定位,不透明度或变换后代,按树的顺序分为以下类别:


        >所有定位后代的’z-index:auto’或’z-index:0’,按树顺序排列。对于那些使用’z-index:auto’的人,请将该元素视为
        它创建了一个新的堆叠上下文,但任何定位的后代和
        实际创建新堆叠上下文的后代应该是
        被认为是父堆叠上下文的一部分,而不是这个新的。对于
        那些’z-index:0’处理生成的堆栈上下文
        原子。
        >所有不透明度后代的不透明度小于1,按树顺序,创建一个原子生成的堆叠上下文。
        >所有使用变换而非变换的变换后代,按树顺序,创建以原子方式生成的堆叠上下文。

        >堆叠由z-index顺序大于或等于1的定位后代形成的上下文(最小的第一个)然后树
        订购。

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

        在4.1节中,绘制了儿童的背景

        在第4.4点,绘制了儿童的边界。

        第4点完成后,您的代码段的所有背景和边框都已绘制

        现在,在第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>

        另一个片段,在文档中显示了几点:

        请注意,步骤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>

猜你在找的HTML相关文章