页面元素谁上谁下的体位总结

从浏览器渲染说起

一个页面的渲染,大致有下几个步骤

这里直接看最后一步Composite: 渲染层合并,这步是渲染最后一个步骤,作用就是把之前绘制的图层(如果有PS的经验的话图层很好理解)按照规定的顺序合并成一个图层,元素的层叠谁在上面谁在下面的关系,就在这步里被规定被最终在浏览器里体现出来了。

那么这个对层叠理解有什么用呢?。。。。。。。。。。并没什么卵用,只是最近看到了而已,科科,直接进入正题吧,个人总结,会比较乱。

挂两篇大神的文章

普通我上还是你上的几种体位

简单说几种常见情况:

  • 文档中后来的居上

结构如下,这里默认box都有长宽和不同的背景颜色

1
2
<div class="you"></div>
<div class="me"></div>

很显然如果有一个负值margin就会看到我上你下的情况

  • z-index正值>auto(0)>负值前面的居上

这里首先要明白的是z-index只针对position不是static的元素起作用。所以我们这里说起z-index,那这个元素一定是和position一起使用。而如果只指定position,那么该元素会默认z-index:auto, have a look

1
2
3
4
5
6
7
8
9
10
11
12
<div class="you"></div>
<div class="me"></div>
<style>
.you {
position: relative;
}
.me {
position: relaive;
z-index: -1;
margin-top: -10px;
}
</style>

嗯,这里就下了

  • float的元素和position不为static的元素比普通文档流的居上

就不演示了!


好了,上面的四种情况算是最正常也是比较容易理解的情况了吧,那么问题就来了,如果我float了和你z-index: -1了发生重叠呢?如果你z-inidex: auto又或z-inidex: 1了呢? 是不是要愣一下呢哈哈哈,不急,看个宝贝。
盗来的图
嗒哒,什么属性的元素有什么样的层叠等级,按照这张图上面的问题就简单了,float在负值z-index上,在auto或正值之下。咦?这里咋还有inline-block的事呢,还这么高等级捏??这是因为内容要大于布局,不展开(顶部有鑫旭大神的文章,里面有做介绍)。

OK,我想是时候迎接这篇文章的高潮了,有孩子的抱稳了!上图中位于最底层的层叠上下文五个大字看到没有?目前我们都是把要比较元素放在以同一个层叠上下文为基底的环境内做比较,但是所有元素都会在这一个环境内吗?咳咳,我喝口水慢慢喷:

一个重要的概念——层叠上下文(stacking context)

不得不说这个词对于我这样的人从中文上理解简直是十脸懵逼

上下文?context?WTF?好吧,其实这东西是一个抽象的概念,如果让我来翻译它,我觉得比较合适的解释:创建层叠上下文的元素自己会成为一个参考对象

既然是一个参考对象,那么谁来参考它呢?答案是它的子元素们(其实这并不是完全正确,但是可以先这么认为)。然后这个参考对象什么时候会被用到呢?

直接干巴巴的说个情景:

页面里你随便找两个元素(为了区分就是吧),如果我和你要比较谁更高人一等怎么办呢?

  1. 浏览器会做的就是不断向上检索祖辈元素,直到这个祖辈创建过层叠上下文(也就是这个祖辈可以当做参考对象)
    得到了两个元素各自的参考对象(这里称呼为我爸爸你爸爸)然后呢,这时就分两种情况!分两种情况!分两种情况:

  2. 如果我爸爸你爸爸是一个人!OK,这时就是在一个层叠上下文中了,就可以按照上面盗来的层叠等级图进行谁上谁下的判断了

  3. 如果是不一样的呢???那事情就变得有趣多了——就不!会!去!进!行!比!较!了!!。这场较量一下子会变成我爸爸你爸爸间的战斗了(嘿,你崽子敢动我崽子。动你崽子咋滴啦,你不服咱两干啊。干!)
    然后他们两就干起来了,他们两干的方式就和我和你一样,去找各自参考对象——得到我爷爷你爷爷。然后来看是否同一个人,如果是的话我爸爸你爸爸就是在一个层叠上下文中了,就会在爷爷辈这个参考对象上比出个高低,而这个高低!就是的高低,换句话说就是高低由我和你的参考对象决定了。如果我爷爷你爷爷还是不一样呢…..Go on

讲的有点绕是不是,没关系!再听我讲几句,你会更晕的

接下来说谁会是参考对象(创建了层叠上下文)

  • html天然就是,这就可以去把前面那些简单的例子套进来了,因为它们的参考对象都是html根元素了,所以可以直接在同一环境(上下文)比较。
  • position不为staticz-index不是auto的元素
  • displayflexz-index不是auto的元素
  • opacity不等于1
  • transform不等于none

好了,到这个时候就该上例子了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<div class="me">
<div class="you"></div>
</div>
</html>
<style>
.me {
width: 100px;
height: 100px;
}
.you {
width: 100px;
height: 100px;
left: 50px;
position: relative;
z-index: -1;
}
</style>

来理解下,you在这里和me做比较,比较开始,首先you寻找参考对象,上一层me是吗?显然不是,因为me没有触发上面任一条件创建层叠上下文,所以继续往上寻找,找到html,好的,是!

对于me呢,也直接往上找到html,所以这个例子里me和you是在以html为参考对象进行比较,换句话说就是在html创建的层叠上下文环境中进行比较

然后按照七阶图,负值index在block元素之下!所以me在you之上

然后我们修改下me,加个。。。就加个opacity

1
2
3
4
5
.me {
opacity: .9;
width: 100px;
height: 100px;
}

按照之前的思路演算一遍,you的参考对象变成me了!而me仍然是html,然后me和html再做比较,me参考对象是html,html的参考对象是html,OK,在同一上下文了,me(you的爸爸)明显高于html(me的爸爸),所以you高于me

就不举复杂的例子了,其实都一样,用这个规则去分析,我自己觉得会很清晰!

有错误或者写的烂欢迎指出来批评讨论!