说到CSS世界的层叠规则,不少人会想到z-index,翻译成中文,叫作"z轴的顺序"。事实上,抛开z-index只有在部分元素中(如定位元素)生效的条件,任何“元素”都无需借助z-index的支持会有本身的层叠规则,这个层叠顺序是基于z轴的。这里咱们须要了解一个概念,尽管咱们平时看到的电脑屏幕是“二维”的平面,但事实上CSS世界的概念是“三维”的,他和咱们人所在的世界同样,通过任意一点能够有三条互相垂直的直线,固然这是三维空间的概念,和本文并没有多大关系。css
既然都是三维世界的层叠关系,那咱们以本身的世界为例,来谈谈05年春晚的一个节目——千手观音。 html
千手观音这个节目很好的展示了三维世界的层叠关系与所展示的“视觉效果”。以图片平面为xy平面,视觉上呈现了排在第一个的人的完整图像,已第一我的为准,排在他后面的人,构成了三维世界的z轴,因为后面的人在xy平面上的“大部分”图像都被遮挡,只能看到因为角度不一样而呈现出来的手臂,所以最终在"xy"平面上呈现出千手观音的效果。(三维世界的坐标轴以下所示,我不敢在上图中乱涂乱画,我怕文字狱) 浏览器
经过上面这个例子,咱们须要明白一条CSS三维世界的第一准则:永远不会有两个在z轴上重合的“元素”! 布局
在理解CSS世界的层叠规则以前,咱们必需要了解两个关键词——层叠上下文和层叠水平。本章的前面两个小节就单独来说一讲这两个关键词。首先,什么是层叠上下文?这是HTML中的一个官方的三维概念,这个说法听起来有点像以前提到过的“块状格式化上下文”(BFC),这里咱们复习一下块状格式化上下文作了一件什么事情,就是声明了xxx属性的元素他一不当心拥有了xxx特性。放在这里也是同理,在CSS世界中,只要当前元素拥有了某些属性(如position:relative;定位加上z-index不为auto),就会使得当前元素被“层叠上下文”。那么这个被“层叠上下文”会使当前元素拥有什么特性呢? 测试
在讲BFC的时候,咱们提到了一个结界的概念,放在这里,也依然适用,拥有层叠上下文特性的元素会生成一个“层叠结界”,这个“层叠结界”内部的全部元素会永远的被束缚在某一段z轴空间内部,且永远不能打破这个外层的“层叠结界”。这也就是为何有时候咱们的子元素设置了z-index:9999仍然可能会被其余元素覆盖,这颇有多是他的父元素不争气,排在了覆盖物的后面致使的。以下例所示: flex
<div class="box1">我是配角</div>
<div class="box2">
<div class="son">我才是主角,我被父元素的层叠上下文束缚了</div>
</div>
<style> .box1{ position: absolute; z-index: 1; width: 200px; height: 200px; background: yellow; opacity: 0.7; } .box2{ width: 400px; height: 300px; position: absolute; z-index: 0; background: green; text-align: right; } .box2>.son{ position: relative; z-index: 9999; } </style>
复制代码
在本开头,我提出了一个概念——CSS世界中任何两个“元素”不会在z轴上重合,因为不是全部元素须要被“CSS层叠上下文”,但全部的元素都须要有个z轴上的显示顺序,所以对于这些没有被“层叠上下文”的元素如何显示的问题就须要层叠水平的帮忙了。事实上,咱们须要明确一个概念,就是全部的元素都拥有层叠水平,这是一个默认的“计算值”,但因为在声明了层叠上下文后,这个计算值能够忽略不计,所以一般咱们只在同一个层叠上下文中考虑层叠水平的问题。 ui
说了这么多,你可能仍然不能明白层叠水平是个什么东西,这里咱们就用个例子来讲明一下。 spa
<div id="father">
<span id="son1">我是大儿子</span>
<span id="son2">我是二儿子</span>
</div>
复制代码
在上例中,咱们的父容器里面有两个span标签,这两个span标签并不会产生所谓的“重叠”,但他们其实并无处在同一个z坐标中,并且能够确定的是,二儿子的显示顺序要优于大儿子,这是由普通元素的默认层叠水平决定的,至于为何是二儿子在大儿子上面,后面会详细说到。 翻译
在理解了层叠上下文和层叠水平的概念后,咱们能够来好好聊一聊CSS世界的显示规则了,也就是本节要说的层叠顺序。因为全部元素都自带层叠规则,所以CSS制定了一套详细的标准来规范元素在z轴上的显示顺序。以下图所示: 设计
能够看到,在每个层叠上下文的结界中,任何内部元素的层级都要高于backgroud/border,所以background/border组成了层叠上下文的“地板”,而层叠上下文的“天花板”取决于内部元素的z-index:正值的大小(理论上是这样)。
在这个层叠顺序表中,咱们能够注意到,在层叠上下文结界中,默认层级最高的是inline/inline-block元素,层级最低的永远是background和border,默认层级居中的是一些布局用的盒子,这也符合CSS设计的标准,以图文展现为主,其次是布局,最次儿的就是装饰性的background和border属性了。
除了上面提到的CSS2.1的标准,做者在CSS层叠领域总结了两条黄金准则,在元素发生层叠的时候,其覆盖关系遵循下面两条准则:
(1)谁大谁上:当具备明显的层叠水平标识的时候,如生效的z-index属性值,在同一个层叠上下文结界馁,层叠水平值大的那一个覆盖小的那一个。
(2)后来居上:当元素层叠水平一致的时候,在DOM流中处于后面的元素会覆盖前面的元素。
结合这两条准则,就能够解释任何元素发生重叠时的显示顺序的问题了。
在本章中咱们了解了不少CSS世界中层叠规则的概念,下面咱们须要结合上面三个小节的概念作一个综合性的测试,主要是为了验证CSS2.1的标准在谷歌浏览器下的表现是否依旧稳定。
第一个测试验证:inline>float>block>background
在进行测试的时候,须要用到margin负边距使得元素重叠,测试代码以下:
<!-- 综合测试1 -->
<div class="father">
<span class="inline">inline元素</span>
<div class="float"></div>
<div class="block"></div>
</div>
<style> .father{ position: relative; background: rgb(255,255,0); } .block{ background: rgb(255, 0, 0); width: 100px; height: 120px; } .float{ float: left; background: rgb(0,255,255); width: 100px; height: 100px; margin-left: 50px; } .inline{ margin-left: -100px; background: rgb(0,255,0); } </style>
复制代码
结果代表inline>float>block>background的结论成立。
第二个测试验证:z-index正值>z-index:0约等于z-index:auto>z-index负值
<!-- 综合测试2 -->
<div class="father">
<div class="zIndex-1">负的z-index</div>
<div class="zIndexAuto">z-index:auto</div>
<div class="zIndex0">z-index:0</div>
<div class="zIndex1">正z-index</div>
</div>
<style> .father{ position: relative; background: rgb(255,255,0); } .zIndex-1{ position: absolute; width: 100px; height: 200px; background: rgb(255,0,0); left: 0; top: 0px; z-index: -1; } .zIndex0{ position: absolute; width: 100px; height: 100px; background: rgb(0,255,0); left: 0; top: 100px; z-index: 0; } .zIndexAuto{ position: absolute; width: 100px; height: 150px; background: rgb(255,0,255); left: 0; top: 50px; z-index: auto; } .zIndex1{ position: absolute; width: 100px; height: 50px; background: rgb(0,255,255); left: 0; top: 150px; z-index: 1; } </style>
复制代码
在层叠水平上,z-index:auto和z-index:0的层叠顺序是相同的,所以遵循后来居上的原则,可是z-index:0和z-index:auto在建立层叠上下文结界上有本质区别,这点在下一章节会详细论述,感兴趣的同窗能够测试下上述全部元素混杂在一块儿的时候的层叠顺序。本章主要就是些概念性的东西,为下一章深刻了解作个准备。
不忘初心,方得始终
喜欢博主的童鞋能够扫描二维码加博主好友~ 也能够扫中间二维码入驻博主的粉丝群(708637831)~固然你也能够扫描二维码打赏并直接包养帅气的博主一枚。