DOM层级顺序,大概来讲就是DOM节点在z轴方向(垂直于屏幕向外的方向)的显示优先级。为了调整DOM层级顺序,咱们想到的每每就是用CSS的z-index属性来控制。虽然看着很简单,可是有时在使用时,咱们有时也许会碰到一些一些奇奇怪怪的问题:html
其实看似简单的层级顺序它本身的一套规则,理解这些规则能够帮助咱们在开发中少踩坑。web
在不设置position属性(或设置成static)的状况下,文档流后面的DOM节点会覆盖前面的DOM节点。浏览器
<div id="a">A</div> <div id="b">B</div>
PS:怎么样来让文档流中的节点叠在一块儿呢?好比咱们能够设置DOM的margin-top
为负数,这样就让两个节点叠在起一块儿了。不过为了简化说明,并无把这些写出来。下同。spa
定位节点(position属性设置为relative,absolute或fixed的节点)会覆盖非定位节点(不设置position属性或position属性设为static的节点)3d
<div id="a" style="position: relative">A</div> <div id="b">B</div>
根据顺序规则和定位规则, 咱们能够作出更加复杂的结构。A和 B 都设为非定位节点,A 的子节点 A-1 设定定位节点。code
<div id="a"> <div id="a-1" style="position: relative">A</div> </div> <div id="b">B</div>
z-index属性仅对定位节点生效。orm
有三个DOM节点,其定位为static。可是A的z-index最大,可是依旧是在最底部,C的z-index最小,而在最顶部,所以可知z-index并未生效,此时为顺序规则在生效。htm
<div id="a" style="z-index: 2">A</div> <div id="b" style="z-index: 1">B</div> <div id="b" style="z-index: 0">B</div>
咱们将B和C的position设置为relative以后,顺序发生了变化。根据参与者规则和定位规则,A不是定位节点,因此即便z-index最大,仍是在最底部。而根据参与规则和默认值规则(下一节介绍),B和C都是定位节点,且B的z-index要大于C,因此B在最顶部。blog
<div id="a" style="z-index: 2">A</div> <div id="b" style="position: relative; z-index: 1">B</div> <div id="b" style="position: relative; z-index: 0">B</div>
<div id="a" style="position: relative; z-index: 1">A</div> <div id="b" style="position: relative; z-index: 0">B</div> <div id="c" style="position: relative">C</div> <div id="d" style="position: relative; z-index: 0">D</div>
两个节点A和B都是定位节点,若是节点A的z-index值比节点B的大,那么节点A的子元素都会覆盖在节点B以及节点B的子节点上。ip
<div id="a" style="position: relative; z-index: 1"> <div id="a-1">A-1</div> </div> <div id="b" style="position: relative; z-index: 0"> <div id="b-1">B-1</div> </div>
若是定位节点A和B的z-index值同样大,那么根据顺序规则,B会覆盖A,那么即便A的子节点的z-index比B的子节点大,B的子节点仍是会覆盖A的子节点。(这就是为何即便咱们把A-1的z-index设置得很大,依然没法盖住B节点的缘由)。
<div id="a" style="position: relative; z-index: 0"> <div id="a-1" style="position: relative; z-index: 2">A-1</div> </div> <div id="b" style="position: relative; z-index: 0"> <div id="b-1" style="position: relative; z-index: 1">B-1</div> </div>
定位节点,且z-index有整数值的(不包括z-index:auto),会被放置到一个与DOM节点不同的层级树里。
在下面的DOM节点中,A和B是兄弟节点,可是在层级树种,A和B-1才是兄弟节点(由于他们都是Root下的第一层含有整数z-index的定位节点),因此A在B和B-1之上。虽然A-1的z-index比B-1的小,可是根据从父规则,A-1也在B-1之上。
<div id="a" style="position: relative; z-index: 2"> <div id="a-1" style="position: relative; z-index: 0">A-1</div> </div> <div id="b"> <div id="b-1" style="position: relative; z-index: 1">B-1</div> </div>
下面这个更复杂的层级树,聪明的你能看明白为何节点层级是这样的了吗?
<div id="a" style="position: relative"> <div id="a-1" style="position: relative; z-index: 100">A-1</div> </div> <div id="b"> <div id="b-1" style="position: relative"> <div id="b-1-1" style="position: relative; z-index: 10">B-1-1</div> </div> </div> <div id="c" style="position: relative"> <div id="c-1"> <div id="c-1-1"> <div id="c-1-1-1" style="position: relative; z-index: 1">C-1-1-1</div> </div> </div> </div>
介绍了这么多规则,是在是很差理解,又很难记。其实,要理解这些规则,咱们只须要理解一个概念就好了,它就是层叠上下文。
层叠上下文是HTML元素的三维概念,这些HTML元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的z轴上延伸,HTML元素依据其自身属性按照优先级顺序占用层叠上下文的空间。
知足一下其中一个条件,便可产生一个层叠上下文:
位置 | 描述 | CSS |
---|---|---|
1(底部) | 包含该层叠上下文的父元素 | |
2 | 负堆叠顺序的子元素 | z-index: <negative integer>; position: relative (or absolute or fixed) |
3 | 文档流中,非内联,非定位子元素 | display: /* not inline */; position: static |
4 | 非定位浮动子元素 | float: left (or right); position: static |
5 | 内联流,非定位子元素 | display: inline; position: static |
6 | 堆叠顺序为0的子元素 | z-index: auto (or 0); position: position: relative(or absolute or fixed) |
7(顶部) | 堆叠顺序为正的子元素 | z-index: <positive integer>; position: relative(or absolute or fixed) |