8.1.9. z-index
本节能学到的知识:
- 深入理解嵌套表现及z-index的计算规则;
- 详细介绍元素层叠表现、顺序及CSS的一些属性对层叠上下文的作用;
- 分享z-index相关事件经验。
8.1.9.1. z-index 基础
了解z-index的语法,支持的属性值等
含义 : z-index属性指定了元素及其子元素的“z顺序”,而z顺序可以决定当元素发生覆盖的时候,哪个元素在上面。通常一个较大z-index值的元素会覆盖较低的那一个
支持的属性值:
- auto; 默认值
<integer>
数值- inherit; 继承
基本特性:
- 支持负值
- 支持css3 animation动画
- 在css2.1时代,需要和定位元素配合使用
如果不考虑css3,只有定位元素(position:relative/absolute/fixed/sticky)的z-index才有作用,在css3中有例外
8.1.9.2. z-index 与css定位属性
嵌套表现以及z-index计算规则
z-index 只对定位元素有响应
如果定位元素z-index没有发生嵌套:
- 后来居上的准则
- 哪个大,哪个上
如果定位元素z-index发生嵌套:
祖先优先原则(非 auto,只能是数值。)
CSS2.1:z-index:auto 当前层叠上下文的生成盒子层叠水平是0.盒子(除非是根元素)不会创建一个新的层叠上下文
8.1.9.3. 理解CSS中的层叠上下文和层叠水平
元素层叠表现基础且重要的概念
层叠上下文(stacking context) 是HTML元素中的一个三维概念,表示元素在z轴上有了“可以高人一等。”
具有层叠上下文的元素有:
- 页面根元素天生具有层叠上下问,称之为“根层叠上下文”
- z-index值为数值的定位元素也具有层叠上下文
- 其他属性
层叠水平(stacking level) 层叠上下文中的每个元素都有一个层叠水平,决定了同一个层叠上下文中元素在z轴上的显示顺序。
遵循“后来居上”和“谁大谁上”的层叠准则
特性:
- 层叠上下文可以嵌套,组合成一个分层次的层叠上下文
- 每个层叠上下文和兄弟元素独立:当进行层叠变化或渲染的时候,只需要考虑后代元素。
- 每个层叠上下文是自成体系的:当元素的内容被层叠后,整个元素被认为是在父层的层叠顺序中。
8.1.9.4. 理解层叠顺序 - stacking order
元素发生层叠时候有着特定的垂直显示顺序
著名的7阶层叠水平(stacking level)
层叠顺序的意义
规范元素重叠时候的呈现规则
为何层叠顺序是这样的?
比如float元素不是应该更屌一点,为什么inline元素还在float元素上呢?
因为:更符合页面加载的功能和视觉呈现
<div class="item1">
<img src="~@/assets/demo-java.jpg"/>
以前浮动课程就讲过,浮动原本设计的作用是实现文章环绕图片的效果。
如果图片和文字发生重叠,显然,是后面的文字要优先显示的,因为,文字比让图片重要。
就像这里,我就放一个美女图片,你再有洪荒之力也猜不到我想表达的内容吧,嘿嘿
</div>
.item1{
img {
float left
margin-right -30px // 浮动后右移,和文字重叠
}
}
文字是内联元素,在7阶层叠水平中,内联元素和inline-block是平级,所以是后来居上
8.1.9.5. z-index与层叠上下文
解释z-index的实际行为表现
- 定位元素默认z-index:auto 可以看成是z-index:0
- z-index不为auto的定位元素会创建层叠上下文
- z-index层叠顺序的比较止步于父级层叠上下文
为何定位元素要覆盖普通元素? 在7阶层叠水平表中,z-index:auto高于水平盒子
从层叠顺序上讲,z-index:auto可以看成z-index:0; 但是从层叠上下文来讲,两者却有着本质差异!
这章节最重要的是,要学会看为什么一些z-index底的元素反而在上面,最最重要的要去套7阶层叠水平图的规范。只要一套,基本上就懂了,还有边框和背景色,内容之分,所以要注意
8.1.9.6. 其他css属性与层叠上下文
介绍其他也会创建层叠上下文的css属性
- z-index 值不为auto的flex项(父元素display:flex|inline-flex)
- 元素的opacity值不是1
- 元素的transform值不是none
- 元素mix-blend-mode值不是normal
- 元素的filter值不是none
- 元素的isolation值是isolate
- postion:fixed声明 (chrome等blink/webkit内核浏览器)
- will-change指定的属性值为上面任意一个
- 元素的-webkit-overflow-scrolling设为touch
8.1.9.7. z-index 与其他css属性层叠上下文
非定位元素层叠上下文和z-index关系大揭秘
- 不支持z-index的层叠上下文元素的层叠顺序均是z-index:auto级别
依赖z-index的层叠上下文元素的层叠顺序取决于z-index值
依赖z-index值创建层叠上下文的情况:
- position值为relative/absolute或fixed
- display:flex|inline-flex容器的子flex项
层叠上下文导致的有趣的现象
<div class="item2">
<div class="box">
<p>看什么看,还不赶快叫师娘</p>
<img src="~@/assets/demo-java.jpg"/>
</div>
</div>
.item2{
text-align center
img{
animation:fadein 3s infinite;
}
.box{
position relative
display inline-block
}
p{
position absolute
bottom 2px
left 0
right 0
color #fff
font-size 15px
line-height 2
background rgba(1, 8, 5, 0.38)
}
@keyframes fadein{
from{
opacity 0
}
to{
opacity 1
}
}
}
上面的代码写了一个把文字叠加到图片上的一个效果,然后让图片的透明度从0变为1的一个动画效果。 实际的结果却出现了,连文字都被一起变成透明的了
这里为什么会照成这样的效果呢?
- 元素的opacity值不是1,的时候会创建层叠上下文,且这里没有指定z-index,所以是 auto
- 定位元素也会创建层叠上下文,且这里没有指定z-index,所以是 auto
- 他们的层级是一样的权重,都是auto。后来居上,所以文字被覆盖掉了
- (如果把dom顺序:p标签放到图片后面,效果则比较完美)因为层叠水平是一样的,后来居上嘛。可以尝试修改下z-index的值,就能验证了
8.1.9.8. 实践分享
- 最小化影响原则
- 不犯二准则
- 组件层级计数器
- 可访问性隐藏
8.1.9.8.1. 最小化影响原则
目的:避免z-index嵌套层叠关系混乱 原因:
- 元素的层叠水平主要由所在的层叠上下文决定
- ie7 z-index:auto也会新建层叠上下文
做法
- 避免使用定位属性
- 定位属性从大容器平级分离为私有小容器
8.1.9.8.2. 不犯二准则
目的: 避免z-index混乱,一山比一山高的样式问题 原因: 多人协作以及后期维护 做法: 对于非浮层元素,避免设置z-index值,z-index值没有任何道理需要超过2 ------ 不犯二准则
8.1.9.8.3. 组件层级计数器
目的: 避免浮层组件因z-index被覆盖的问题 原因:
- 总会遇到意想不到的高层级元素
组件的覆盖规则具有动态性
比如弹框,后面弹出来的覆盖前面的弹框。
做法: 组件层级计数器方法 ;通过JS获得body下子元素的最大z-index值
8.1.9.8.4. 负值与可访问性隐藏
可访问性隐藏: 人肉眼不可见,但是辅助设备可以识别(比如把文字设置left为负数-999,人烟看不见了,但是屏幕阅读器能看到)
z-index负值元素在层叠上下文的背景之上,其他元素之下
利用这种特性我们实现一个小示例
<div class="item3">
<h3>原始按钮</h3>
<form>
<input required/>
<input type="submit">
</form>
<h3>帅气按钮</h3>
<form>
<input required/>
<input type="submit" id="submit">
<label for="submit">提交</label>
</form>
</div>
.item3{
[type=submit]{
position absolute
z-index -1
}
label{
background #0f5499
padding 10px
color #fff
}
}
原始的按钮比较丑陋,用自定义标签然后使用 for指向id,for的标签就有指向的功能了,但是我们要利用"可访问性隐藏"特性来把原始按钮隐藏,这里的隐藏不是看不见,就必须第一个按钮,在我们的css里面也把第一个原始按钮也作用上了,能看到但是点击不了,所以在第二帅气按钮里面,只要我们把 新的lable元素增加背景色就能把原始的按钮挡住了。
当然在不考虑低版本的浏览器的时候,直接把原始按钮display:none,也能有效果