css层叠规则
一直认为z-index就是用来描述定义一个元素在屏幕Z轴上的堆叠顺序。z-index值越大在Z轴上就越靠上,也就是离屏幕观察者越近。
1.首先,z-index属性值并不是在任何元素上都有效果。它仅在定位元素(定义了position属性,且属性值为非static值的元素)上有效果
2.判断元素在Z轴上的堆叠顺序,不仅仅是直接比较两个元素的z-index值的大小,这个堆叠顺序实际由元素的层叠上下文、层叠等级共同决定。
什么是“层叠上下文”
层叠上下文是css中的一个三维概念,它描述了元素在页面上的垂直堆叠顺序。
如果一个元素是层叠上下文元素,我们可以理解为这个元素在Z轴上就“高人一等”,最终表现就是它离屏幕观察者更近。
1、HTML中的根元素本身就具有层叠上下文,称为“根层叠上下文”。
2、普通元素设置position属性为非static值并设置z-index属性为具体数值,产生层叠上下文。
3、CSS3中的新属性也可以产生层叠上下文,如下:
父元素的display属性值为flex|inline-flex,子元素z-index属性值不为auto的时候,子元素为层叠上下文元素;
元素的opacity属性值不是1;
元素的transform属性值不是none;
元素mix-blend-mode属性值不是normal`;
元素的filter属性值不是none;
元素的isolation属性值是isolate;
will-change指定的属性值为上面任意一个;
元素的-webkit-overflow-scrolling属性值设置为touch
层叠上下文元素相当于是一个容器,容器里装着其他元素。不同容器内的元素的高低由容器决定,但不会突破容器。
z-index应该这样理解:每一个层叠上下文就是一层楼,而该楼层的z-index就是楼梯。1楼层的楼梯值再大,也不可能比2层楼高。 (结合代码)
什么是“层叠等级”
那么,层叠等级指的又是什么?
- 在同一个层叠上下文中,它描述定义的是该层叠上下文中的层叠上下文元素在
Z轴上的上下顺序。 - 在其他普通元素中,它描述定义的是这些普通元素在
Z轴上的上下顺序。
把z轴想象一个生物界,狮子物种和蚂蚁物种是没有可比性的,不在一个纬度上比较。
所有元素都有层叠等级,包括层叠上下文元素,也包括普通元素
再类比回“层叠上下文”和“层叠等级”,就得出一个结论:
- 普通元素的层叠等级优先由其所在的层叠上下文决定。
- 层叠等级的比较只有在当前层叠上下文元素中才有意义。不同层叠上下文中比较层叠等级是没有意义的。
什么是“层叠顺序”
说完“层叠上下文”和“层叠等级”,我们再来说说“层叠顺序”。“层叠顺序”(stacking order)表示元素发生层叠时按照特定的顺序规则在Z轴上垂直显示。由此可见,前面所说的“层叠上下文”和“层叠等级”是一种概念,而这里的“层叠顺序”是一种规则。
层叠顺序遵循上面途中的规则。
这里值得注意的是:
- 左上角"层叠上下文
background/border"指的是层叠上下文元素的背景和边框。 inline/inline-block元素的层叠顺序要高于block(块级)/float(浮动)元素。- 单纯考虑层叠顺序,
z-index: auto和z-index: 0在同一层级,但这两个属性值本身是有根本区别的。
对于上面第2条,为什么inline/inline-block元素的层叠顺序要高于block(块级)/float(浮动)元素?
其实很简单,像border/background属于装饰元素的属性,浮动和块级元素一般用来页面布局,而网页设计之初最重要的就是文字内容,因此要让内容的层叠顺序相当高,这样当发生层叠时,重要的文字、图片内容才可以优先显示在屏幕上,保证其不被覆盖。
总结
总结1
对于z-index的使用规律,MDN实际上就简单一句话:”z-index越大则越上层,有爹则拼爹“。
1,同一个层叠上下文中,z-index越大则越上层。 2,不同层级上下文,则层级越高越上层。 3,层级等级和层叠等级相同的,则后来的覆盖之前的。
层叠顺序
总结2
1.Chrome等WebKit内核浏览器下,position: fixed元素天然层叠上下文元素,无需z-index为数字。
2.一旦普通元素具有了层叠上下文,其层叠顺序就会变高。那他的层叠顺序究竟在哪个位置、哪个级别呢
1)如果层叠上下文元素不依赖z-index数值,其层叠顺序是z-index: auto,可看成z-index:0级别;
2)如果层叠上下文元素依赖z-index数值,则其层叠顺序由z-index值决定
3.定位元素为什么会层叠在普通元素上
元素一旦成为定位元素,其z-index值会自动生效,此时其z-index就是默认的auto,也就是0级别,就会覆盖inline/block/float元素,而不支持z-index的层叠上下文元素天然是z-index: auto级别,层叠上下文元素与定位元素是一个层叠顺序的,当他们发生层叠时遵循的是后来居上的准则
总结3
z-index是支持负值的
问题: 一个定位元素设置z-index为负值,就会跑到页面的背后,隐藏掉,看不到了,实际是,有时隐藏不了,有时隐藏的了。
z-index虽然是负数,但是无法突破当前层叠上下文所包裹的小世界
z-index负值渲染过程就是一个寻找第一个层叠上下文元素的过程,然后层叠顺序止步于这个层叠上下文元素
z负数隐藏子元素
实践经验
能不设置 z-index 就不要去设置,设置请三思。
定位元素天生高于普通元素
设置了 relative 或者 absolute 的元素会高于其他元素,因此这种情况下完全可以不设置 z-index,如果设置了 z-index 就会生成新的层叠上下文,可能会造成堆叠的混乱。
另外因为设置了 fixed 即使不设置 z-index 也会生成一个层叠上下文,因此 fixed 元素会高于其他所有的普通元素(定位元素和非定位元素)。但如果页面中有定位元素设置了正的 z-index,就不得不给 fixed 元素加一个更大 z-index 了。
子元素层级受到父层叠上下文的影响
当设置了一个 z-index 产生了层叠上下文后,需要考虑当前元素会不会成为别的元素的父元素,如果在多人合作中经常互相改代码或者引用组件,如果某个地方产生了层叠上下文,那子元素的层级就会受到该父元素的影响从而导致达不到想要的层级。
比如将一个弹窗组件放到了一个父元素中,父元素有层叠上下文,这样就会导致弹窗组件达不到自己想要的高度。