1.z-index基础
z-index属性指定了元素及其子元素的[z顺序],而[z顺序]可以决定
当元素发生覆盖的时候,哪个元素在上面。通常一个较大z-index值的元素会覆盖较低的那一个。
z-index支持的属性值:
1. z-index:auto;默认值,如果不对z-index设置,默认为auto;
2. z-index:;整数值,z-index:1,z-index:2等
3. z-index:inherit;继承
z-index基本特性:
1. 支持负值;
2. 支持CSS3 animation动画;
3. 在CSS2.1时代,不考虑CSS3,z-index要起作用需要和定位元素配合使用,只有定位元素(position:relative/absolute/fix/sticky)设置z-index才有作用(CSS3中有例外);
2. z-index与定位元素
如果定位元素发生了覆盖,且没有嵌套(不是一个定位元素里面嵌套着另一个定位元素),谁在上面遵守下面两个准则:
1. 后来居上的准则,后面的覆盖前面的;
2. z-index哪个大,哪个上;
demo 1:
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
后面的定位元素覆盖前面的定位元素在上面渲染。
demo 2:
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
z-index值大的在上面覆盖z-index值小的
另一种情况:定位元素z-index发生了嵌套,谁在上面遵循如下原则:
祖先优先原则;
demo :
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
可以看到嵌套了的z-index定位元素,尽管前面的子元素的z-index值大,还是后面的图片覆盖了前面的,这里就遵循了祖先优先原则。
前提:祖先的z-index值是数值不是auto
demo :
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
当第一个图片元素的祖先元素z-index值为auto时,祖先优先原则就会失效,z-index:auto可以看成是z-index:0,尽管第二个图片元素的祖先元素z-index值比0大,但还是第一个图片覆盖第二个图片。
CSS2.1:(z-index:auto时)当前层叠上下文的生成盒子层叠水平是0。盒子(除非是根元素)不会创建一个新的层叠上下文。这是起作用的反而是子元素的z-index值。第一个子元素的z-index大于第二个子元素的,所以会覆盖。
3.CSS中层叠上下文和层叠水平
层叠上下文(stacking content)是HTML元素中的一个三维概念,表示元素在z轴上有了“高人一等”。
页面根元素天生具有层叠上下文,称之为"根层叠上下文"。
z-index值为数值的定位元素也具有层叠上下文。
层叠上下文中的每个元素都有一个层叠水平(stacking level),决定了同一个层叠上下文中元素在z轴上的显示顺序。几乎所有的元素都有层叠水平,但是要放在层叠上下文中来看。
层叠水平和z-index不是一个东西。普通元素也有层叠水平,但z-index只在定位元素上起作用。
同一个层叠上下文中的层叠元素遵循“后来居上”和“谁大谁上”的层叠原则。
层叠上下文几个特性:
4.理解元素的层叠顺序(stacking order)
层叠顺序:元素发生层叠时候有着特定的垂直显示顺序。
著名的7阶层叠水平(stacking level),用来判断元素发生层叠时谁在上谁在下:
Paste_Image.png
层叠元素的意义:
规范元素重叠时候的呈现规则。
为何层叠顺序是上面图片中的样子?比如:为何内联元素会覆盖浮动元素?
之所以是这样的七阶,是因为这样更符合加载的功能和视觉呈现
一般来说,像background/border是用来装饰的,块状元素、浮动元素都是用来布局的,而内联元素绝大部分是内容:图片、文字,因为内容是页面最重要的部分,因此层叠必须水平要高,重要的东西越要往上面放!
demo :
Document
![](b.jpg)
以前浮动课学过,浮动设计的作用是实现文字环绕图片的效果。如果文字和
图片发生重叠,显然,是后面的文字要优先显示的,因为,文字比图片重要。
这里把图片变成了浮动元素,内容(内联元素)覆盖了图片浮动元素,比浮动元素的层叠水平要高。
Paste_Image.png
demo:
Document
display:inline-block
display:block;
Paste_Image.png
内联元素比块状元素的层叠水平高,上面的背景色覆盖了下面的,但是下面的文字覆盖了上面的背景色。这是因为:背景色的覆盖是层叠顺序,文字的覆盖是后来居上原则。文字是inline元素和inline-block是平级的,所以这里要用到后来居上原则
5.z-index与层叠上下文(解释z-index的实际行为表现)
三个行为要点:
1. 定位元素默认的`z-index:auto`可以看成是z-index:0
2.z-index不为auto的定位元素会创建层叠上下文;
3.z-index层叠顺序的比较止步于父级层叠上下文;
第一个行为要点:定位元素默认的z-index:auto可以看成是z-index:0;
demo 1:
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
根据后来居上原则后面的元素会覆盖前面的元素
demo 2:
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
第一个图片变成定位元素之后,前面的图片又覆盖了后面的,这是因为当变为定位元素后,没有对z-index设置值,所以默认值为auto,从层叠顺序上看,这时可以把z-index:auto看成是z-index:0。这时再对照七阶层叠那个图:
Paste_Image.png
第二个行为要点:z-index不为auto的定位元素会创建层叠上下文
demo:
Document
![](a.jpg)
Paste_Image.png
绝对定位元素只是一个普通元素,并不具有层叠上下文。此时图片的层叠上下文是页面根元素。所以背景色会覆盖图片。
一旦给父元素z-index值为数值不为auto时,
Document
![](a.jpg)
Paste_Image.png
当我们给父元素.div设置z-index:0;时,就创建了层叠上下文,此时图片的层叠上下为文就变成了容器。z-index负值的层叠顺序在层叠上下文元素的背景色之上。
Paste_Image.png
从层叠顺序上讲,z-index:auto可以看成z-index:0。但是从层叠上下文来讲,两者却有着本质差异!本质差异:z-index:auto不可以创建层叠上下文,z-index:0可以。
第三个行为要点:z-index受限于层叠上下文
demo:
Document
![](a.jpg)
![](b.jpg)
Paste_Image.png
可以看到尽管第一个图片的z-index远远大于第二个图片,但是由于第二个图片的父元素的层叠顺序大于第一个图片父元素的层叠顺序,所以最终的行为表现仍然是后面的覆盖前面的。
6.其他CSS属性与层叠上下文(不只是z-index)
1.页面根元素天生具有层叠上下文,称之为"根层叠上下文"。
2.z-index值为数值的定位元素(相对或绝对)也具有层叠上下文。
3.其他属性......创建层叠上下文。
Paste_Image.png
demo 1:display:flex与层叠上下文
Document
![](a.jpg)
Paste_Image.png
由于.box不是层叠上下文元素,所以图片没有覆盖背景色,此时图片的层叠上下文为根元素。
当我们为.box设置display:flex之后:
Paste_Image.png
图片覆盖了背景色。
注意:给.box设置display:flex不是.box变为了层叠上下文元素,而是它的子项变成了层叠上下文元素
Document
![](a.jpg)
Paste_Image.png
当对它的子元素的z-index值设置.box>div{ z-index: auto; }后,.box元素的子项就不再是层叠上下文元素了
demo 2 :opacity ≠ 1 与层叠上下文
Document
![](a.jpg)
Paste_Image.png
当我们为.box元素设置opacity为0.5时:
Paste_Image.png
图片显示在了背景色上面,这是因为opacity ≠ 1的元素为层叠上下文元素。
demo 3 :transform ≠ none 与层叠上下文
Document
![](a.jpg)
Paste_Image.png
transform ≠ none的元素为层叠上下文元素.
......以上不过多赘述。
7.z-index与其它CSS属性层叠上下文(非定位元素层叠上下文和z-index关系)
1.不支持z-index的层叠上下文元素的层叠顺序均是z-index:auto级别(不支持z-index的层叠上下文,指的就是那些CSS属性创建的层叠上下文)。
Paste_Image.png
举个例子:
Paste_Image.png
上图中img1、img2、img3、img4、img5依次相互覆盖,img1对应七阶层叠水平中的第五阶,是inline水平元素,img2、img4、img5是不依赖z-index的层叠上下文,img3是z-index:auto,它们都对应第六阶,属于同阶,遵循后来居上原则,依次覆盖。
2.依赖z-index的层叠上下文元素的层叠顺序取决于z-index值
依赖z-index值创建层叠上下文的情况:
1.position值为relative/absolute或fixed(部分浏览器);
2.display:flex|inline-flex容器的子flex项;
Paste_Image.png
Paste_Image.png
上图中的.box元素是普通元素,它的子项才是层叠上下文元素,所以不仅被第一张图片覆盖,还被父元素的背景色覆盖
Paste_Image.png
Paste_Image.png
z-index和层叠上下文
z-index基础介绍:
三维坐标空间里,x轴通常用来表示水平位置,y轴来表示垂直位置,还有z轴来表示在纸面内外方向上的位置,像下面的图片一样:
css允许的z-index的值是
● auto (自动,默认值)
● (整数)
● inherit (继承)
当设置成整数时,值越大越靠近用户。
如果有两个元素放在了一起,占据了一块共同的区域,那么有着较大z-index值的元素就会掩盖有着较低z-index值的元素在共同区域的那一部分。
关于z-index的三个思考
● 当一个设置了z-index值的定位元素与正常的文档流中的元素相互重叠的时候,谁会被置于上方?
● 当定位元素与浮动元素相互重叠的时候,谁会被置于上方?
● z-index必须要与定位一起使用才会生效吗?
● z-index大的元素一定会遮挡z-index小的元素吗?
解决上面的问题需要深入理解z-index的原理,需要知道层叠上下文和层叠顺序。
层叠上下文的概念:
层叠上下文就是html中的一个三维概念。相当于在水平面创建了一个z轴,有了层叠上下文的元素会离用户更近。它包含了一组层叠层的元素。我们所创建的每一个网页都有一个默认的层叠上下文,层叠上下文的根就是html,其他的所有元素都会在这个层叠上下文占据一个层叠水平,或高或低。
层叠顺序:
层叠顺序:这是一种规则,表示元素发生重叠时,在z轴上的显示顺序。
在一个层叠上下文中,有七种层叠顺序:
(1) 背景和边框:建立层叠上下文的元素的背景和边框,层叠中的最低级别
(2) 负的z-index:z-index 为负值时形成的层叠上下文
(3) 块级盒子: 文档流中正常的块级元素
(4) 浮动盒子:非定位的浮动盒子
(5) 行内盒:文档流内的行内级盒子
(6) z-index:0 定位元素,这些元素建立了新的层叠上下文。
(7) 正的z-index:层叠中的最高级别。
页面中内联元素的层叠顺序要比浮动元素和块状元素都高的原因,浮动和块级盒子主要用来布局,而内联的元素用来显示页面内容。所以比起他的要高。
ps: 图上缺少的信息
inline和inline-block是一个同一个level
z-index:0实际上和z-index:auto单纯从层叠水平上看,是可以看成是一样的。
层叠顺序规则
谁大谁上:当具有明显的层叠水平标示的时候,比如说z-index值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个
后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在DOM流中处于后面的元素会覆盖前面的元素。
层叠上下文元素的特性
● 层叠上下文的层叠水平要比普通元素高;
● 层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的层叠上下文。
● 每个层叠上下文不会影响它的兄弟元素,当进行层叠变化或渲染的时,只和该元素的后代元素有关。
● 每个层叠上下文是独立的,当元素发生层叠的时,它的层叠顺序依赖在父层叠上下文的层叠顺序中。
层叠上下文的创建
(1)根层叠上下文:
指的是页面根元素,也就是html元素。这就是为什么,绝对定位元素在left/top等值定位的时候,如果没有其他定位元素影响,会相对浏览器窗口定位的原因。
(2)定位元素
含有position的值是relative或absolute的定位元素,以及FireFox/IE浏览器(Chrome等webkit内核浏览器是fixed的自动形成层叠上下文,无需将z-index设置成数值)下含有position:fixed的定位元素,当其z-index值不是auto的时候,会创建层叠上下文。
demo:
(1)
结果:
(2)
结果:
原因:
z-index 值是auto,是一个普通元素,两个img层比较不受父级的影响,按照规则谁大谁上,于是,z-index为2的猫覆盖值为1的狗
z-index:0会创建一个层叠上下文。此时,层叠规则就发生了变化。层叠上下文特性里最后一条规则,每个层叠上下文都是独立的。两个img的层叠顺序比较变成了优先比较其父级层叠上下文元素的层叠顺序。由于两者都是z-index:0,一样大,此时,遵循层叠规则后来居上,根据在DOM出现的先后顺序决定谁在上面,于是,位于后面的狗覆盖猫。此时img元素上的z-index是没有任何意义的。
E6/IE7浏览器有个bug,就是z-index:auto的定位元素也会创建层叠上下文。
(3) CSS3下的层叠上下文
CSS3的一些新属性,会创建局部的层叠上下文,并且transform属性会改变绝对定位的字元素的包含块。
以下几种情况会产生新的层叠上下文:
1.z-index值不为auto的flex项(父元素display:flex|inline-flex).
2.元素的opacity值不是1.
3.元素的transform值不是none.
4.元素mix-blend-mode值不是normal.
5.元素的filter值不是none.
6.元素的isolation值是isolate.
7.will-change指定的属性值为上面任意一个。
8.元素的-webkit-overflow-scrolling设为touch.
display:flex|inline-flex与层叠上下文
需要满足两个条件才能形成层叠上下文:
(1) 父级需要是display:flex/inline-flex
(2) 子元素的z-index不是auto,必须是数值。
此时,这个子元素为层叠上下文元素,没错,注意了,是子元素,不是flex父级元素
demo:
.box div {
width: 300px;
height: 300px;
background-color: pink;
z-index: 101;
}
.box div img {
width: 400px;
height: 200px;
position: relative;
z-index: -1;
}
结果:
原因:此时的div是一个普通的元素,它上面设置的z-index是无效的,img的负值z-index会被块级元素所遮挡。
接上:
.box {
display: flex;
}
结果:
div加上flex值之后,此时的z-index就会生效,会使它的子元素既内部的div形成层叠上下文。根据7层的层叠顺序,background的那层会被负的z-index的那层所遮挡。
flex的出现打破了传统的z-index必须与定位的元素一起使用才会生效的观念。
opacity与层叠上下文
div {
width: 300px;
height: 300px;
background-color: pink;
}
div img {
width: 400px;
height: 200px;
position: relative;
z-index: -1;
}
结果:
给div加一个opacity的属性:
div {
width: 300px;
height: 300px;
background-color: pink;
opacity: 0.5; /* 添加opcity属性 */
}
只要设置的opacity的值不是1,就会形成层叠上下文。
表现结果:
transform对层叠上下文的影响
同上,对外层的div设置transform: rotate(15deg),会形成层叠上下文,导致图片显示在div的上面。
transform除了建立局部的层叠上下文还会改变绝对定位(固定定位也是绝对定位的一种)子元素的包含块,
包含块的概念:一些盒子根据它外面的矩形盒子计算得到自身的定位和大小,这个外层的矩形盒子就是包含块。
对固定定位的元素的影响:
正常的固定定位的包含块是视口,加了transform就不一样了
div {
width: 100px;
height: 100px;
}
#fixed {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: blue;
}
#transform {
background: red;
padding: 20px;
}
fixed将会铺满整个屏幕。
结果:
上面加上
#transform {
transform: scale(1);
}
结果:
原因,fixed的包含块不再是视口,而是transform这个div最边缘。所以fixed的宽高均为140px
对绝对定位的元素的影响:
#relative {
position: relative;
width: 100px;
height: 100px;
background: green;
}
#absolute {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: blue;
}
#transform {
background: red;
width: 50px;
height: 50px;
}
此时absolute的包含块为relative的内边距盒的边缘盒。所以absolute的宽高是100px
给transform div加上transform属性
结果:
由于transform创建了局部层叠上下文,absolute的包含块不再是 relative而是transform了,根据这一新的包含块,得新宽和高为50px。
只要是有了transform这个属性不论它的值是什么都会影响绝对定位的子包含块。
总结 :
层叠上下文的元素的层叠顺序在哪一层:
依赖z-index值的元素,根据z-index的值来决定。
不依赖z-index的值的元素,它们的z-index的auto值相当于z-index:0级别。
第二种情况解释了为什么定位的元素会覆盖掉普通流中的元素。定位的元素,会默认加上z-index: auto,按照7种层叠顺序,会遮盖普通流的元素。
当z-index的值同是auto,就是说层叠上下文的元素和定位的元素处于同一个层叠顺序时,当她们发生重叠时,后面的元素会遮盖上面的元素:
上面的元素调换位置:
z-index本质上还是谁大谁在上面,虽然css3新加的一些属性使z-index变的复杂,最常见的影响可能就是flex布局导致的,但是规则还是按照7种层叠顺序来排布。