z-index决定了元素以及其子元素的z顺序,而z顺序决定当元素发生覆盖的时候,哪个元素可以在上面,通常较大z-index值的元素可以覆盖较低的那个。
一. z-index概览
首先我们先来大致认识一下z-index,z-index的属性值只有三个:auto(默认值),integer(整数值),inherit(继承)。除此以外,z-index有一些基本的特性:
- 支持负值
- 支持CSS3 animation动画
- 在CSS2.1时代,需要配合定位使用
值得注意的是第三点,也就是说如果不设置元素的定位(position),z-index也就不会生效。
二. z-index的定位规则
接下来我们来看看z-index的定位规则,一般来说,如果在没有嵌套的情况下,元素的层叠顺序遵循一下的准则:
1.后来居上原则
所谓后来居上,也就是说靠后的元素会覆盖靠前的元素,比如:
<div class="box" style="background:blue;position:absolute"></div>
<div class="box" style="background:yellow;position:absolute"></div>
黄色的方块出现比较晚,会覆盖蓝色的方块。
2.z-index值为大的优先
如果对上面的代码设置z-index,那结果可能也就不一样了:
<div class="box" style="background:blue;position:absolute;z-index:2"></div>
<div class="box" style="background:yellow;position:absolute;z-index:1"></div>
我们可以看到,蓝色元素覆盖了黄色元素,可见,z-index可以改变元素的默认层叠顺序。
那么,如果z-index发生了嵌套呢,情况可能会有一点复杂,但其实也遵循相应的准则
1.祖先优先原则
<div class="box-container" style="position:relative;z-index:1">
<div class="box box1" style="background:blue;position:absolute;z-index:2"></div>
</div>
<div class="box-container" style="position:relative;z-index:1">
<div class="box box2" style="background:yellow;position:absolute;z-index:1"></div>
</div>
我们可以看到结果如下:
可见,虽然box1的z-index值高于box2,当是这种时候应该考虑它们的祖先,祖先元素在z-index相同的情况下遵循后来居上原则,所以box2会覆盖box1。
当然,这么比较的前提是z-index的值为数值,如果z-index的值为auto,其结果就截然相反了:
<div class="box-container" style="position:relative;z-index:auto">
<div class="box box1" style="background:blue;position:absolute;z-index:2"></div>
</div>
<div class="box-container" style="position:relative;z-index:1">
<div class="box box2" style="background:yellow;position:absolute;z-index:1"></div>
</div>
其结果就是:
为什么呢?根据CSS2.1的定义,在z-index为auto的情况下,当前层叠上下文的层叠水平为0。盒子不会创建一个新的层叠上下文。
三. 层叠上下文与层叠水平
我们看到了两个定义,层叠上下文和层叠水平,那么,什么是层叠上下文呢?层叠上下文是HTML元素的三维概念,表示元素在z轴上可以高人一等,注意,层叠上下文相当于元素的一个属性,在不同的情况下,元素可能拥有这个属性,也可能没有。总结起来,一般两种情况可以让元素拥有层叠上下文:
- 页面根元素天生就具有层叠上下文,称之为根元素层叠上下文
- z-index得值为数值的元素也可以拥有层叠上下文
层叠上下文中的每一个元素都拥有一个层叠水平,决定了同一层元素在该层内的层叠顺序,遵循z-index的两个计算准则。
层叠上下文拥有几个特性:
- 层叠上下文可以嵌套,组成几个分层次的层叠上下文。这意味着一个层叠上下文元素的子元素也可以拥有层叠上下文。
- 每个层叠上下文和兄弟元素独立,当进行变化或渲染时,只需要考虑后代元素,也就是,层叠上下文元素的层叠次序发生变化,不会影响兄弟元素,只会影响后代元素。
- 每个层叠上下文都自成体系,子元素之间的相互比较全依赖同级父元素的层叠次序。
了解了层叠上下文,我们再来看看层叠水平,其实,除了层叠上下文元素外,每一个元素都拥有层叠水平,网上有一张图很好的总结了元素层叠水平的比较准则:
为什么是这个层叠顺序呢,我们一定会很好奇,为什么内联元素的层叠顺序会高于浮动元素,事实上,CSS如此定义是为了更好得表现页面,这个层叠顺序可以划分三类,装饰->布局->内容,越往后面优先级越高,浮动元素属于布局,而inline属于内容,自然优先级会比浮动元素高一些。我们可以感受一下:
<div class="box box1" style="background:blue;float:left;"></div>
<div class="box box2" style="background:yellow;display:inline-block;margin-left:-20px;"></div>
结果如下:
最后我们来看看z-index和层叠上下文的关系:
- 定位元素默认z-index为auto可以看成z-index为0
- z-index不为auto的定位元素会创建层叠上下文
- z-index的层叠次序比较止步于父级层叠上下文