1. 堆叠顺序
堆叠顺序(stacking order):HTML 内元素发生层叠的时候的特定垂直顺序,即元素在用户视线方向上的顺序。
一般而言,div 以内在层叠顺序上对于视觉有影响的一般有以下几个:
- background
- border
- 块级元素
- 内联元素
- 浮动块级元素
- 定位块级元素
接下来,我们一个一个来测试一下他们的堆叠顺序。 ####1. 首先,测试一下 background 和 border 的堆叠顺序。 在日常写页面中,很大可能是这样的:
HTML
<body>
<div class="parent"></div>
</body>
复制代码
CSS
.parent{
height:40px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
复制代码
.parent{
height:40px;
border:10px solid rgba(255,0,0,0.4);
background:#000;
}
复制代码
2. 接下来,给 div 加一个内联元素和一个块级元素
HTML
<body>
<div class="parent">
<span>内联元素</span>
<div class="child"></div>
</div>
</body>
复制代码
CSS
.parent{
height:150px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
span{
color:#fff;
}
.child{
width:80px;
height:50px;
background:green;
}
复制代码
显示效果
CSS
.parent{
height:150px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
span{
color:#fff;
margin-left:-10px;
}
.child{
width:80px;
height:50px;
background:green;
margin-left:-10px;
}
复制代码
显示效果
CSS
.parent{
height:150px;
border:10px solid rgba(255,0,0,1);
background:#000;
}
span{
color:#fff;
margin-left:-10px;
}
.child{
width:80px;
height:50px;
background:green;
margin-left:-10px;
margin-top:-10px;
}
复制代码
显示效果
3. 接下来该比较一下浮动元素了
先加一个浮动元素,背景色为蓝色。
HTML
<body>
<div class="parent">
<span>内联元素</span>
<div class="child"></div>
<div class="float"></div>
</div>
</body>
复制代码
CSS
.float{
width:80px;
height:50px;
background:blue;
float:left;
}
复制代码
显示效果
.float{
width:80px;
height:50px;
background:blue;
float:left;
margin-top: -60px;
}
复制代码
4. 接下来是定位(position:relative;和position:absolute;)元素
依然是加一个定位元素
HTML
<body>
<div class="parent">
<span>内联元素</span>
<div class="child"></div>
<div class="float"></div>
<div class="relative"></div>
</div>
</body>
复制代码
CSS
.relative{
width:70px;
height:50px;
background:yellow;
position:relative;
}
复制代码
显示效果
.relative{
width:70px;
height:50px;
background:yellow;
position:relative;
margin-top:-50px;
}
复制代码
可以看到,position:relative; 的元素直接盖住了目前已知最高等级的内联元素,说明 position:relative; 的元素的堆叠顺序比内联元素的要大。 接下来看一下 position:absolute; 将上面 position:relative; 改为 position:absolute;
.relative{
width:70px;
height:50px;
background:yellow;
position:absolute;
margin-top:-50px;
}
复制代码
从图片可以看出结果是一摸一样的,说明 position:relative和 position:absolute; 有一样的堆叠顺序。 所以:定位元素 > 内联元素 > 浮动元素 > 块级元素 > border > background
5. 最后是 z-index 的影响
首先要知道,z-index 生效的前提是该元素是 position 属性值是非static的元素,此时的 z-index为 auto。再添加一个元素,使它的 z-index生效
HTML
<body>
<div class="parent">
<span>内联元素</span>
<div class="child"></div>
<div class="float"></div>
<div class="relative"></div>
<div class="z-index"></div>
</div>
</body>
复制代码
CSS
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:1;
}
复制代码
显示效果
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:1;
margin-top: -40px;
}
复制代码
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:-1;
margin-top:-40px;
}
复制代码
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:-1;
margin-top:0px;
}
复制代码
.z-index{
width:90px;
height:50px;
background:orange;
position:absolute;
z-index:-1;
margin-top:70px;
}
复制代码
可以看到,橙色有一部分被背景盖住了,说明:
正z-index > 浮动元素 > 内联元素 > 浮动元素 > 块级元素 > border > background > 负z-index
综合上面所有内容,元素的堆叠顺序就出来了。 就是下面这个:
正z-index > 浮动元素 > 内联元素 > 浮动元素 > 块级元素 > border > background > 负z-index
上面的顺序,越大的离用户越近。
2. 堆叠上下文
堆叠上下文:stacking context,类似与作用域,由不同的CSS属性造成的一类具有相同特征的东西,并没有特定的概念。堆叠上下文影响的是元素 CSS 属性中的 z-index,父元素是否是堆叠上下文,对具有z-index属性的子元素的堆叠顺序有影响。
文档中的层叠上下文由满足以下任意一个条件的元素形成:
- 根元素 (HTML),
- z-index 值不为 "auto"的 绝对/相对定位,
- 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex的元素
- opacity 属性值小于 1 的元素(参考 the specification for opacity),
- transform 属性值不为 "none"的元素,
- mix-blend-mode 属性值不为 "normal"的元素,
- filter值不为“none”的元素,
- perspective值不为“none”的元素,
- isolation 属性被设置为 "isolate"的元素,
- position: fixed
- 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值(参考 这篇文章)
- -webkit-overflow-scrolling 属性被设置 "touch"的元素
接下来看一下堆叠上下文对 z-index 的影响: 首先创建一个父元素的 div 作为容器,然后添加两个子 div ,两个子 div 里分别添加一个子 div
HTML
<body>
<div class="parent">
<div class="a relative">
<div class="aaa">aaa</div>
</div>
<div class="b relative">
<div class="bbb">bbb</div>
</div>
</div>
</body>
复制代码
接下来,使用 CSS 添加样式,此时页面内有一个堆叠上下文=》html 元素
CSS
.parent{
height:200px;
border:10px solid red;
background:black;
padding:10px;
}
.a,.b{
border:1px solid red;
width:200px;
height:100px;
background:green;
}
.aaa,.bbb{
background:yellow;
}
.relative{
position:relative;
}
复制代码
显示效果
接下来给 bbb 添加一个 z-index:1;并使它移动到 aaa 的位置。
.bbb{
z-index:1;
margin-top:-90px;
}
复制代码
.a,.b{
border:1px solid red;
width:200px;
height:100px;
background:green;
z-index:0;
}
复制代码
.aaa{
z-index:2;
}
复制代码
接下来让 parent 元素形成堆叠上下文,并给 a 和 b 一个负z-index
.parent{
height:200px;
border:10px solid red;
background:black;
padding:10px;
position:relative;
z-index:0;
}
.a,.b{
border:1px solid red;
width:200px;
height:100px;
background:green;
}
.aaa,.bbb{
background:yellow;
}
.relative{
position:relative;
z-index:-1;
margin-top:50px;
}
复制代码
3. 总结
- 普通块级元素中,z轴元素的堆叠顺序如下: 正z-index > 内联元素 > 浮动元素 > 块级元素 > border > background >负z-index
- 堆叠上下文中,z轴元素的堆叠顺序如下: 正z-index > 内联元素 > 浮动元素 > 块级元素 > 负z-index > border > background
- z轴顺序遵循两个原则:
- 谁大谁上
- 大小一样,后来居上
部分参考自:
- http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/
- https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context