元素重叠时背景的奇怪行为 [英] Strange behavior of background when elements are overlapping

查看:91
本文介绍了元素重叠时背景的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是情况(代码使用Chrome,Firefox和IE11测试)
$ b

  body {margin:0;背景:粉红色; color:#fff;}。box {margin-top:20px; background:red;}。bottom {text-align:right;背景:绿色; animation:animate 2s infinite linear linear;} @ keyframes animate {from {margin-top:10px; }到{margin-top:-40px; }}  

 < div class =box>一些内容< / div>< div class =bottom>其他内容< / code> 


$ b

发生了什么?



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



这里的动画没有什么可做的,我只是用它来更好地展示行为。我们可以简单地在没有动画的情况下添加负边距,并且我们会有相同的事情:

  body {margin:0;背景:粉红色; color:#fff;}。box {margin-top:20px; background:red;}。bottom {margin-top:-10px; text-align:right;背景:green;}  

 < div class =box >一些内容< / div>< div class =bottom>其他内容< / div>  



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




顺便说一句,我们都知道CSS有一些棘手的问题我们不会怀疑当我们第一次面对他们时(比如边缘折叠,从身体到html的背景传播,空白问题等等),但是他们在某个地方被清楚地解释了,我希望找到一个官方资源我可以清楚地理解这一点,不仅可以得到类似于可能发生这种情况的原因是......我怀疑这与......有关我认为这与...有关......等。






我对此的意见/解释



我认为像文字这样的内容比背景和其他视觉样式更重要,所以也许当我们有重叠时,我们将所有文字放在最上面,所有其他样式放在最下面,我们决定

这是一个更复杂的例子:



body {margin:0;背景:粉红色;颜色:#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:n-child(2){background:blue;边框:3px纯黄色;颜色:#000;}身体:nth-​​child(3){背景:绿色; border:3px solid orange;}

< div>一些内容< / div>< div>其他内容< / div>< div>更多内容< / div>



我们可以清楚地看到 visual stack 如下所示(从下到上): 第一 strong> div(背景+边框)

  • 第二个 div(背景+边框)的样式

  • 第三 div(背景+边框)

  • 文本内容第一 div

  • 文本第二 div

  • $ b的第二 div
  • 文字内容的内容
    $ b


    重要提示:在回答之前,请注意我并未寻求修复此问题或解决方法为了避免这一点。只需添加 position:relative ,行为就会消失,我们可以使用 z-index 来决定堆叠。我希望了解为什么会发生这种情况。




    生成堆栈上下文的元素的后代的绘制顺序(请参阅z-index属性)为:


    1. 如果元素是根元素:


      1. 整个元素的背景颜色
      2. 元素的背景图像,在整个画布上,锚定在原点上,如果它被绘制为根元素,则使用该原点。

      3. 如果元素是


        • 块,列表项或其他块等效项:


          1. 元素的背景颜色,除非它是根元素。元素的背景图像,除非它是根元素。
          2. li>
          3. 元素的列规则。

          4. 元素的边框。


          5. 否则,如果元素是块级表:


            1. 表背景(颜色然后图像)除非它是r
            2. 列组背景(彩色图像)。

            3. 列背景(彩色图像)。


            4. 行背景(彩色图像)。

            5. 单元格背景(彩色图像)。

            6. 单元格列规则适用于多列。

            7. 所有表格边界(以树状顺序为分隔边界)。



            8. 以z-index顺序排列由具有负Z指数(不包括0)的后代形成的上下文(最负第一个)然后是
              树顺序。
            9. 对于树中顺序的所有流入,未定位的块级别的后代:


              • 如果元素是块,列表项或其他块的等价物:


                1. 元素的背景颜色。
                2. >
                3. 元素的背景图像。

                4. 元素的列规则。

                5. 元素的边框。 b $ b

                6. 否则,该元素是一个表:


                  1. 表背景(颜色和图像)。

                  2. 栏背景(彩色图像)。

                  3. 行组背景(彩色图像)。

                  4. 行背景(彩色图像)。

                  5. 单元格背景(彩色图像)。
                  6. >
                  7. 单元格列规则(多列)。
                  8. 所有表格边框(以树状顺序为分隔边界)。

                  9. ol>

            10. 所有未定位的浮动后代,按树形顺序排列。对于其中的每一个,将该元素视为创建新的堆栈
              上下文,但任何定位的后代和后代实际上
              创建新的堆栈上下文都被视为父元素的一部分
              堆栈
            11. 如果元素是一个生成堆栈上下文的内联元素,则:


              1. 对于元素所在的每个线框:


                1. 跳转到7.2.1中该线框中元素的框(在树中订单)。



            12. 否则:先为元素,然后为所有它的流入,非定位,块级别的子树按顺序排列:


              1. 如果元素是块级替换元素,然后:原子地替换的内容。

              2. 否则,对于该元素的每一行:


                1. 对于该元素的子元素的每个框,在该行中框,按树形顺序排列:元素的背景颜色。元素的背景图像。 元素的背景图像 / li>

                2. 元素的列规则。

                3. 元素的边界。

                4. 对于内联元素:


                  1. 对于此行框中的所有元素in-flow,未定位的行内级别的子元素以及所有
                    元素内的文本行为在这个线框上,按照树的顺序:


                    1. 如果这是一段文字,则:


                      1. 任何下划线会影响元素的文本,按照树中的元素的顺序应用下划线(例如,最深的
                        元素的下划线(如果有的话)被涂成最顶层,而根元素b b元素的下划线(如果有的话)绘制在最下面)。
                      2. 任何上划线会影响元素的文本,按照应用上划线的元素的树形顺序(例如,最深的
                        元素的上划线,如果有的话如果有的话,绘制最上面的和根
                        元素的上划线,如果有的话,绘制到最底部)。
                      3. 文本

                      4. 任何影响元素的文本,按照应用直通的元素的树形顺序(例如,如果有的话,最深的
                        元素的直通线(如果有的话)被绘成最顶层,并且根元素
                        元素的直通线,最后绘制到底)。


                    2. 否则,跳转到该元素的7.2.1




                      1. li>对于其中的每个元素,将元素视为创建新的堆叠上下文,但是实际创建新的堆叠上下文的定位后代和后代
                        被视为父元素堆栈上下文的一部分,不是新的。


                    3. 对于内联级替换元素:


                      1. 被替换的内容是自动的。


                      2. 可选地,元素的大纲(参见下面的10)。




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


                    4. $ b $如果元素是块级别的,元素的轮廓(参见下面的10)。 $ b




















                      所有定位的不透明或变形后代,


                      1. 所有定位后代都具有'z-index:auto'或'z-index:0',按树形顺序排列。对于那些使用'z-index:auto'的对象来说,就好像
                        创建了一个新的堆栈上下文一样,但是实际上创建一个新的堆栈上下文的定位后代和
                        后代应该是
                        将其视为父级堆叠上下文的一部分,而不是这个新的。对于
                        ,那些'z-index:0'的对象会以原子方式处理堆叠上下文生成的

                      2. 所有不透明度的后代,不透明度小于1,按照树的顺序,创建一个以原子方式生成的堆栈上下文。
                      3. li>

                      4. 以z-index顺序(最小的第一个),然后树$ b,定位后代形成的上下文与z-索引大于或等于1 $ b $订单。


    现在请认真参考 w3c涂料订单文档

    4.1,孩子的背景是绘制的

    在4.4点,儿童的边界被绘制出来。

    点4完成后,你的代码片段的所有背景和边框都被绘制成

    现在,在第7.2.1.5.1.1.3节中,孩子的文本被绘制出来。



    这是你看到的行为。



    还要注意,很容易改变这种行为。我们可以激活点8.2,(设置不透明度),它会像您预期的那样绘制:

      body {margin:0;背景:粉红色; color:#fff;}。box {margin-top:20px; background:red;}。bottom {text-align:right;背景:绿色;动画:动画2s无限交替线性; opacity:0.9999;} @ keyframes animate {from {margin-top:10px; }到{margin-top:-40px; }}  

     < div class =box>一些内容< / div>< div class =bottom>其他内容< / div>  

    另一个片段文档:

    请注意,步骤4中的所有边框和背景均在步骤3之后和setp 5之前呈现。但步骤4中的文本是步骤7,因此在步骤5中的文本之后呈现

    div {width:200px; height:100px;边框:实心10px; font-size:40px;}。step3 {border-color:red; background-color:lightpink; z-index:-1;位置:相对; margin-left:10px;}。step41 {border-color:brown;背景颜色:黄色; 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;背景颜色:白色; margin-top:-30px;} div:hover {position:relative;}

     < div class =step3>步骤3否定zindex< / div>< div class =step41> step4在流程中,数字1< / div>< div class =step42 >在流程中,数字2< / div>< div class =step43>在流程中,数字3< / div>< div class =step5> code> 



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

    div {width: 100像素;身高:1.3em;边框:坚实的12px番茄; font-size:18px;} div:hover {position:relative;}

     < div>一长串文本溢出到其他div< / div>< div>< / div>  

    / div>


    Here is the situation (code tested using Chrome, Firefox and 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>

    What's happening?

    As you may see we have two div without any complex styling (simply background-color). I am making the second div to overlap the first one by applying a negative margin-top. I am expecting to see one completely overlapping the other but this is not the case. The second div is sliding between the content and the background of the first one and it's a strange behavior for me.

    The animation has nothing to do here, I simply use it to better show the behavior. We can simply add negative margin without animation and we will have the same thing:

    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>

    So my question is : why such behavior?


    By the way, we all know that there is some tricky things with CSS that we don't suspect when we face them the first time (like margin-collapsing, background propagation from body to html, white space issue,etc...) but they are clearly explained somewhere and I hope to find an official resource where I can clearly understand this and not only get something like "Maybe this happen because...", "I suspect this related to...", "I think it have something to do with...",etc.


    My opinion/explanation about this

    I suppose content like text are more important than background and other visual styling so maybe when we have overlapping we place all the text at the top and all the other styling at the bottom, we decide about the order inside each group and then we print the result.

    Here is a more complex example:

    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>

    We can clearly see that the visual stack is as follow (starting from bottom to top):

    • Styling of the first div(background + border)
    • Styling of the second div(background + border)
    • Styling of the third div(background + border)
    • text content of the first div
    • text content of the second div
    • text content of the third div

    Important notice: Before answering, please note that I am not looking for a fix to this or how to avoid this. By simply adding position:relative the behavior disappear and we can play with z-index to decide about stacking. Am looking to understand why such thing happen.

    解决方案

    WARNING: Reading the following information can affect your mental health.

    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, list-item, 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, non-positioned, 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, non-positioned, 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, if any, 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, if any, is painted topmost and the root element’s overlining, if any, 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, if any, is painted topmost and the root element’s line-through, if any, 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.

      3. Optionally, if the element is block-level, the outline of the element (see 10 below).

    8. All positioned, opacity or transform descendants, in tree order that fall into the following categories:

      1. All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order. For those with 'z-index: auto', treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one. For those with 'z-index: 0' treat the stacking context generated atomically.

      2. All opacity descendants with opacity less than 1, in tree order, create a stacking context generated atomically.

      3. All transform descendants with transform other than none, in tree order, create a stacking context generated atomically.

    9. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.

    Now seriously, refer to the w3c paint order documentation

    In point 4.1, the background of children is painted

    In point 4.4, the border of children is painted.

    When point 4 is finished, all background and border of your snippet have been painted

    Now, in point 7.2.1.5.1.1.3, the text of the children is painted.

    This is the behaviour that you are seeing.

    Notice also that is easy to change this behaviour. We can activate point 8.2, (setting opacity) and it will paint like you may have expected:

    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>

    Another snippet, showing several point in the document:

    Notice that all the border and background in step 4 are rendered after step 3, and before setp 5. But the text in step 4 is step 7, so is rendered after text in step 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>

    I don know if this counts as an use case : this more natural the initial behaviour the the one set by the elements positioning relative

    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>

    这篇关于元素重叠时背景的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
  • 登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆