Home  >  Article  >  Web Front-end  >  z-index stacking rules_html/css_WEB-ITnose

z-index stacking rules_html/css_WEB-ITnose

WBOY
WBOYOriginal
2016-06-24 11:43:271091browse

1. z-index

z-index is used to control the stacking order when elements overlap.

applies to : positioned elements (i.e. position:relative/absolute/fixed).

The general understanding is that the higher the value, the higher it is. It seems simple, but when z-index is applied to complex HTML element hierarchies, its behavior may be difficult to understand or even unpredictable. Because the stacking rules of z-index are very complicated, we will explain them one by one below.

First explain a noun:

stacking context: The translation is "stacking context". Each element belongs to only one stacking context, and the z-index of the element describes the presentation order of the "z-axis" of the element in the same stacking context.

z-index value:

Default value auto:

When a new box is generated on the page, its default z-index value is auto means that the box will not generate a new local stacking context by itself, but will be in the same stacking context as the parent box.

Positive/negative integer

This integer is the z-index value of the current box. A z-index value of 0 will also generate a local stacking context, so that the z-index of the box's parent box will not be compared with its child box, which is equivalent to isolating the z-index of the parent box and the z-index of the child box.

Next, we will start from the simplest case without using z-index and proceed step by step.

2. Stacking order when z-index is not used

The case of not using z-index is also the default case , that is, when all elements do not use z-index, the stacking order is as follows (from Bottom to top)

  • Background and borders of the root element (i.e. HTML element)
  • Non-positioned descendant elements in the normal flow (the order of these elements is in the order in which they appear in the HTML document)
  • Positioned descendant elements (the order of these elements is according to the order of appearance in the HTML document)
  • Explain the last two rules:

  • Non-positoned element elements in normal flow always precede positioned elements. The element is rendered, so it appears below the positioned element, regardless of the order in which it appears in the HTML.
  • For positioned elements that do not specify a z-index value, their stacking order depends on the order in the HTML document. The elements that appear later have a higher position, regardless of the position attribute.
  • Example:

    <!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>Stacking without z-index</title>    <style type="text/css">    div {        font: 12px Arial;        text-align: center;    }    .bold { font-weight: bold; }    .opacity{opacity: 0.7;}    #normdiv {        height: 70px;        border: 1px dashed #999966;        background-color: #ffffcc;        margin: 0px 50px 0px 50px;    }    #reldiv1 {        height: 100px;        position: relative;        top: 30px;        border: 1px dashed #669966;        background-color: #ccffcc;        margin: 0px 50px 0px 50px;    }    #reldiv2 {        height: 100px;        position: relative;        top: 15px;        left: 20px;        border: 1px dashed #669966;        background-color: #ccffcc;        margin: 0px 50px 0px 50px;    }    #absdiv1 {        position: absolute;        width: 150px;        height: 350px;        top: 10px;        left: 10px;        border: 1px dashed #990000;        background-color: #ffdddd;    }    #absdiv2 {        position: absolute;        width: 150px;        height: 350px;        top: 10px;        right: 10px;        border: 1px dashed #990000;        background-color: #ffdddd;    }</style></head><body>    <br /><br />    <div id="absdiv1" class="opacity">        <br /><span class="bold">DIV #1</span>        <br />position: absolute;    </div>    <div id="reldiv1" class="opacity">        <br /><span class="bold">DIV #2</span>        <br />position: relative;    </div>    <div id="reldiv2" class="opacity">        <br /><span class="bold">DIV #3</span>        <br />position: relative;    </div>    <div id="absdiv2" class="opacity">        <br /><span class="bold">DIV #4</span>        <br />position: absolute;    </div>    <div id="normdiv">        <br /><span class="bold">DIV #5</span>        <br />no positioning    </div></body></html>

    There is a picture and the truth:

    Analysis:

    #5 is not positioned and is in normal flow, so according to the above rules, it is rendered before the positioned elements #1, #2, #3, and #4, at the bottom.

    #1, #2, #3, #4 are all positioned elements, and no z-index is set, so they are rendered in order according to the order they appear in the document. You can remove apacity to see the clear effect.

    3. Floating stacking order

    The z-index position of floating elements is between non-positioned elements and positioned elements. (from bottom to top)

  • The background and border of the root element (i.e. HTML element)
  • Non-positioned descendant elements in the normal flow (the order of these elements is in the order in which they appear in the HTML document)
  • Floating elements (there will be no z-index overlap between floating elements)
  • Inline descendant elements in normal flow
  • Positioned descendant elements (the order of these elements is according to the order of appearance in the HTML document) )
  • The background and border of non-positioned elements are not affected by floating elements, but the content in the element is affected (floating layout characteristics)

    Example:

    <!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>Stacking and float</title>    <style type="text/css">    div {        font: 12px Arial;        text-align: center;    }    .bold { font-weight: bold; }    .opacity{ opacity: 0.7;}    #absdiv1 {        position: absolute;        width: 150px;        height: 200px;        top: 10px;        right: 140px;        border: 1px dashed #990000;        background-color: #ffdddd;    }    #normdiv {/*         opacity: 0.7; */        height: 100px;        border: 1px dashed #999966;        background-color: #ffffcc;        margin: 0px 10px 0px 10px;        text-align: left;    }    #flodiv1 {        margin: 0px 10px 0px 20px;        float: left;        width: 150px;        height: 200px;        border: 1px dashed #009900;        background-color: #ccffcc;    }    #flodiv2 {        margin: 0px 20px 0px 10px;        float: right;        width: 150px;        height: 200px;        border: 1px dashed #009900;        background-color: #ccffcc;    }    #absdiv2 {        position: absolute;        width: 150px;        height: 100px;        top: 130px;        left: 100px;        border: 1px dashed #990000;        background-color: #ffdddd;    }</style></head><body>    <br /><br />    <div id="absdiv1" class="opacity">        <br /><span class="bold">DIV #1</span>        <br />position: absolute;    </div>    <div id="flodiv1" class="opacity">        <br /><span class="bold">DIV #2</span>        <br />float: left;    </div>    <div id="flodiv2" class="opacity">        <br /><span class="bold">DIV #3</span>        <br />float: right;    </div>    <br />    <div id="normdiv">        <br /><span class="bold">DIV #4</span>        <br />no positioning    </div>    <div id="absdiv2" class="opacity">        <br /><span class="bold">DIV #5</span>        <br />position: absolute;    </div></body></html>

    Analysis:

    #4 is a non-positioned element in the normal flow, so it is rendered first, at the bottom.

    #2 #3 One floats left and one floats right, and then it is rendered. Each other will not be overwritten by the z-index value. See picture below.

    #1 #5 is a positioned element and was rendered last. When the browser window becomes smaller, #5 is above #1 because #5 is behind #1 in the HTML document. See picture below.

    4. z-index

    The default stacking order is mentioned above. If you want to change the stacking order of elements, you have to use z-index.

    Note: In the first two cases, although there is overlap between elements, they are all in the same z-layer. Because the z-index attribute is not set, the default rendering layer is layer 0. So be aware that overlays between elements in different layers are a given, but elements in the same layer will also send overrides.

    z-index only applies to positioned elements (i.e. position:relative/absolute/fixed).

    Example:

    <!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>Stacking without z-index</title>    <style type="text/css">    div {        font: 12px Arial;        text-align: center;        opacity: 0.7;    }    .bold { font-weight: bold; }    #normdiv {        z-index: 8;        height: 70px;        border: 1px dashed #999966;        background-color: #ffffcc;        margin: 0px 50px 0px 50px;    }    #reldiv1 {        z-index: 3;        height: 100px;        position: relative;        top: 30px;        border: 1px dashed #669966;        background-color: #ccffcc;        margin: 0px 50px 0px 50px;    }    #reldiv2 {        z-index: 2;        height: 100px;        position: relative;        top: 15px;        left: 20px;        border: 1px dashed #669966;        background-color: #ccffcc;        margin: 0px 50px 0px 50px;    }    #absdiv1 {        z-index: 5;        position: absolute;        width: 150px;        height: 350px;        top: 10px;        left: 10px;        border: 1px dashed #990000;        background-color: #ffdddd;    }    #absdiv2 {        z-index: 1;        position: absolute;        width: 150px;        height: 350px;        top: 10px;        right: 10px;        border: 1px dashed #990000;        background-color: #ffdddd;    }</style></head><body>    <br /><br />    <div id="absdiv1">        <br /><span class="bold">DIV #1</span>        <br />position: absolute;        <br />z-index: 5;    </div>    <div id="reldiv1">        <br /><span class="bold">DIV #2</span>        <br />position: relative;        <br />z-index: 3;    </div>    <div id="reldiv2">        <br /><span class="bold">DIV #3</span>        <br />position: relative;        <br />z-index: 2;    </div>    <div id="absdiv2">        <br /><span class="bold">DIV #4</span>        <br />position: absolute;        <br />z-index: 1;    </div>    <div id="normdiv">        <br /><span class="bold">DIV #5</span>        <br />no positioning        <br />z-index: 8;    </div></body></html>

    5. stacking context

    Why is the stacking order of elements in the previous example affected by z What about the impact of -index? Because these elements have special properties that trigger them to live in a stacking context.

    The question is, what kind of elements will generate stacking context? Meet one of the following rules:

  • 根元素(即HTML元素)
  • 已定位元素(即绝对定位或相对定位)并且z-index不是默认的auto。
  • a flex item with a z-index value other than "auto",
  • 元素opacity属性不为1(See the specification for opacity)
  • 元素transform不为none
  • 元素min-blend-mode不为normal
  • 元素filter属性不为none
  • 元素isolation属性为isolate
  • on mobile WebKit and Chrome 22+, position: fixed always creates a new stacking context, even when z-index is "auto" (See this post)
  • specifing any attribute above in will-change even you don't write themselves directly (See this post)
  • elements with -webkit-overflow-scrolling set to "touch"
  • 在堆叠上下文(stacking context)中 ,子元素的堆叠顺序还是按照上述规则。重点是,子元素的z-index值只在父元素范围内有效。子堆叠上下文被看做是父堆叠上下文中一个独立的模块,相邻的堆叠上下文完全没关系。

    总结几句:

    渲染的时候,先确定小的stacking context中的顺序,一个小的stacking context确定了以后再将其放在父stacking context中堆叠。有种由内而外,由小及大的感觉。

    举例:HTML结果如下,最外层是HTML元素,包含#1 #2 #3,#3中又包含着#4,#5,#6。

    Root(HTML)

  • DIV #1
  • DIV #2
  • DIV #3
  • DIV #4
  • DIV #5
  • DIV #6
  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">  <head>    <title>Understanding CSS z-index: The Stacking Context: Example Source</title>    <style type="text/css">      * {        margin: 0;        }      html {        padding: 20px;        font: 12px/20px Arial, sans-serif;        }      div {        opacity: 0.7;        position: relative;        }      h1 {        font: inherit;        font-weight: bold;        }      #div1, #div2 {        border: 1px solid #696;        padding: 10px;        background-color: #cfc;        }      #div1 {        z-index: 5;        margin-bottom: 190px;        }      #div2 {        z-index: 2;        }      #div3 {        z-index: 4;        opacity: 1;        position: absolute;        top: 40px;        left: 180px;        width: 330px;        border: 1px solid #900;        background-color: #fdd;        padding: 40px 20px 20px;        }      #div4, #div5 {        border: 1px solid #996;        background-color: #ffc;        }      #div4 {        z-index: 6;        margin-bottom: 15px;        padding: 25px 10px 5px;        }      #div5 {        z-index: 1;        margin-top: 15px;        padding: 5px 10px;        }      #div6 {        z-index: 3;        position: absolute;        top: 20px;        left: 180px;        width: 150px;        height: 125px;        border: 1px solid #009;        padding-top: 125px;        background-color: #ddf;        text-align: center;        }    </style>  </head>  <body>    <div id="div1">      <h1>Division Element #1</h1>      <code>position: relative;<br/>      z-index: 5;</code>    </div>    <div id="div2">      <h1>Division Element #2</h1>      <code>position: relative;<br/>      z-index: 2;</code>    </div>    <div id="div3">      <div id="div4">        <h1>Division Element #4</h1>        <code>position: relative;<br/>        z-index: 6;</code>      </div>      <h1>Division Element #3</h1>      <code>position: absolute;<br/>      z-index: 4;</code>      <div id="div5">        <h1>Division Element #5</h1>        <code>position: relative;<br/>        z-index: 1;</code>      </div>         <div id="div6">        <h1>Division Element #6</h1>        <code>position: absolute;<br/>        z-index: 3;</code>      </div>    </div>  </body></html>

    效果:

     

     分析一下:

    1、因为设置了div {opacity: 0.7; position: relative;},所以#1~#6的z-index都是有效的。

    2、为什么#4的z-index比#1高,但是却在#1下面?因为#4的z-index虽然值大,但它的作用域在包含块#3内,而#1的z-index的作用域在html内,和#3同属html,而#3的z-index小于#1。

    3、为什么#2的z-index值比#5的大,还在下面?同上。

    4、#3的z-index是4,但该值和#4,#5,#6的z-index不具有可比性,它们不在一个上下文环境。

    5、如何轻易的判断两个元素的堆叠顺序?

    z-index对堆叠顺序的控制类似于排版时候一大章下几个小节的样子,或者版本号中一个大的版本号跟着小版本号。

    Root-z-index值为默认auto,即0

  • DIV #2 - z-index 值为2
  • DIV #3 - z-index 值为4
  • DIV #5 - z-index值为 1,其父元素z-index值 4,所以最终值为4.1
  • DIV #6 - z-index值为 3,其父元素z-index值 4,所以最终值为4.3
  • DIV #4 - z-index值为 6,其父元素z-index值 4,所以最终值为4.6
  • DIV #1 - z-index 值为5
  • 想看更多例子,可参考文章最后的资源链接。

    六、 合理使用z-index数值

    如果现有三个堆叠的层,从上到下分别为:DIV3,DIV2,DIV1,设置时以100为间隔,设置DIV1的z-index为0,DIV2的z-index为100,设置DIV3的z-index为200。这样后期如果需要在DIV1和DIV2之间加入一些层的话,以10为间隔,设置z-index为10,20等。再需要向z-index0和z-index10之间加入一层的话以5为间隔。这样的写法可以方便后期扩展添加内容。

    尽量避免给z-index使用负值。当然不是绝对的,比如在做图文替换的时候可以使用负值。

    七、资源链接

    MDN z-index

    understanding css z-index

    1. Stacking without z-index : Default stacking rules
    2. Stacking and float : How floating elements are handled
    3. Adding z-index : Using z-index to change default stacking
    4. The stacking context : Notes on the stacking context
    5. Stacking context example 1 : 2-level HTML hierarchy, z-index on the last level
    6. Stacking context example 2 : 2-level HTML hierarchy, z-index on all levels
    7. Stacking context example 3 : 3-level HTML hierarchy, z-index on the second level

    w3c z-index

     

    Statement:
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn