1

stacking context

层叠上下文(stacking context)是HTML中的一个三维的概念.如果一个元素含有层叠上下文,我们就可以理解为这个元素在Z轴上就"高人一等".

Z轴表示用户与屏幕之间并不存在的的垂直线,通俗点讲,就是人眼看屏幕的视线这条垂直于屏幕的线

拥有层叠上下文的元素包括:

  • 页面根元素天生具有层叠上下文,称之为"根层叠上下文"

  • z-index值为数值的定位元素也具有层叠上下文

  • 其他属性也可以具有层叠上下文

stacking level

层叠水平(stacking level),决定了同一个层叠上下文中元素在z轴上的显示顺序

普通元素的层叠水平优先由层叠上下文决定,因此层叠水平的比较只有在当前层叠上下文元素中才有意义

需要注意的是,千万不要把层叠水平和CSS的z-index属性混为一谈.没错,某些情况下z-index确实可以影响层叠水平,但是只限于定位元素以及flex/inline-flex子元素,而层叠水平所有的元素都存在

stacking order

层叠顺序(stacking order)是元素发生层叠时候有着特定的垂直显示顺序

注意,上面的层叠上下文和层叠水平是概念,而这里的层叠顺序是规则

clipboard.png

上图是著名的7阶层叠水平(stacking level)图

上图的层叠顺序inline/inline-block水平盒子(内容)>float浮动盒子以及block块状水平盒子(布局)>background/border(装饰),因为这样更符合页面加载的功能和视觉呈现

层叠顺序实例

在这个例子中,inline-block属性的红色div,inline属性span > float:left属性图片 > block属性绿色div.但是有一点,blockdiv的文字会在inline-blockdiv背景色的上面,因为background层叠顺序最低

z-index与stacking context

  1. 定位元素默认z-index:auto可以看成是z-index:0

  2. z-index不为auto的定位元素会创建层叠上下文(IE7除外,auto也会创建)

  3. z-index层叠顺序的比较止步于父级层叠上下文

三个实例

在第一个例子中,应用了position:relative属性的图片z-index:auto,层叠顺序大于普通inline-block元素,所以定位图片覆盖普通图片

在第二个例子中,父容器设置position:absolute,子元素图片设置position:relative,这时,我们给图片添加z-index:-1,图片跑到背景色后面了,原因是设置了z-index的图片的层叠上下文元素是页面根元素;这时,我们再给父容器添加z-index:0,图片的层叠上下文元素变为父容器,此时,图片又回到背景色之上,因为z-index:-1层叠水平在层叠上下文背景色之上

第三个例子中,虽然第一个子元素设置z-index:999999,第二个子元素z-index:-1,但是它们的层叠上下文起作用的是父元素的z-index,所以第一个图片被第二个图片覆盖

其它属性与层叠上下文

其它参与层叠上下文的属性:

  • z-index值不为autoflex项(父元素display:flex|inline-flex).

  • 元素的opacity值不是1.

  • 元素的transform值不是none.

  • 元素mix-blend-mode值不是normal.

  • 元素的filter值不是none.

  • 元素的isolation值是isolate.

  • position:fixed声明(IE不支持)

  • will-change指定的属性值为上面任意一个.

  • 元素的-webkit-overflow-scrolling设为touch.(移动端)

其它属性与stacking context实例

上面的实例展示了1-8条规则,我们设置8个div盒子,盒子里面放置了8张图片,然后给图片position:relative并且z-index:-1,这时,图片的层叠上下文元素是根层叠上下文,图片被背景色覆盖,然后我们在div盒子分别使用了8条规则,盒子变为层叠上下文,图片出现在背景色上面

这里有个问题,本来是8个图片,这里出现的只有7个,原因是同时存在transformposition:fixed的时候position:fixed失效,导致例7图片层叠上下文被覆盖

z-index与其它css属性层叠上下文

  1. 不依赖z-index的层叠上下文元素的层叠顺序均是z-index:auto级别

  2. 依赖z-index的层叠上下文元素的层叠顺序取决于z-index

依赖z-index值创建层叠上下文的情况:

  • position值为relative/absolute或者fixed(非IE浏览器)

  • display:flex|inline-flex容器的子flex

z-index与定位元素

这个例子中,我们先设置了一个图片层叠上下文,然后设置了一个父容器是flex,子元素z-index:1的层叠上下文;

这里,参与比较的是第一个图片层叠上下文,和flex的子元素图片层叠上下文,决定层叠顺序的是z-index的大小,也就是谁大谁在上面

层叠上下文导致的图片上的文字消失现象

这个例子有个现象,当动画在运行时,文字跑到图片后面去了,基于前面学到的东西,当opacity不为1时,是具有层叠上下文的,层叠级别跟z-index:auto一样,也就是跟absolute是同级的,基于谁大谁在上面的原则,图片会覆盖文字

解决方法:

  1. 调整DOM流先后顺序,将文字放在图片后面

  2. 提高文字的层叠顺序,例如z-index:1

z-index相关实践

1.最小化影响原则

目的:避免z-index嵌套层叠关系混乱

原因:

  1. 元素的层叠水平主要由所在的层叠上下文决定;

  2. IE7 z-index:auto也会新建层叠上下文;

做法:

  1. 避免使用定位属性;

  2. 定位属性从大容器平级分离为私有小容器

可以参考relative相关实践

2.尽量不使用z-index大于2

目的:避免z-index混乱,一个元素比一个元素z-index大的样式问题

原因:多人协作及后期维护

做法:
对于非浮动元素,避免设置z-index值,z-index值没有任何必要超过2

3.组件层级计数器

目的:避免浮层组件因z-index被覆盖的问题

原因:

  1. 总会遇到意想不到的高层级元素

  2. 组件的覆盖规则具有动态性,比如说一个页面有若干个弹框

做法:通过JS获得body下子元素的最大z-index

4.负值z-index与可访问性隐藏

使用可访问性隐藏来解决表单提交按钮低版本浏览器兼容性问题

在本例中,可以使用z-index:-1隐藏原始的submit而使用美化过的label控制提交;如果不需要兼容低版本浏览器可以直接使用display:none

深入理解CSS中的层叠上下文和层叠顺序


人丑就要多读书_
197 声望17 粉丝