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 usedThe 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)
Explain the last two rules:
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 orderThe z-index position of floating elements is between non-positioned elements and positioned elements. (from bottom to top)
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>
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:
在堆叠上下文(stacking context)中 ,子元素的堆叠顺序还是按照上述规则。重点是,子元素的z-index值只在父元素范围内有效。子堆叠上下文被看做是父堆叠上下文中一个独立的模块,相邻的堆叠上下文完全没关系。
总结几句:
渲染的时候,先确定小的stacking context中的顺序,一个小的stacking context确定了以后再将其放在父stacking context中堆叠。有种由内而外,由小及大的感觉。
举例:HTML结果如下,最外层是HTML元素,包含#1 #2 #3,#3中又包含着#4,#5,#6。
Root(HTML)
<!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
想看更多例子,可参考文章最后的资源链接。
六、 合理使用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
w3c z-index