乐趣区

图解一下啥是CSS堆叠上下文,啥是CSS堆叠层叠顺序,让你对css的疑惑少一点?

CSS 堆叠上下文是啥?
我们有一个基本样式的 div,样式如下:
div{
width: 200px;
height: 200px;
border:10px solid red;
padding:15px;
margin:12px;
}

效果如下:

这边有个问题是:border 和 background 是什么关系?
这边有两个选项:

平行的
border 更靠近用户
background 更靠近用户

你们会选择哪个呢?
其实弄懂这个很简单的,我们只需要把 border 设置成半透明就知道答案啦
border:10px solid rgba(255, 0, 0, 0, .3);

从运行结果就可以看出,红色透着绿色,所以是 border 更靠近用户。这时候你就知道 div 不是平的,在垂直屏幕上也是有层次关系的,那这个层次关系就叫做堆叠上下文。
接着我们在 div 里面写个‘你好,世界’,效果如下:

这里又引发了一个问题,这个‘你好,世界’,是在哪层了,是在 border 上还是在 border 与 background 之间呢?
这边我们只需要把 ’ 你好 ’ 移动到 border 上就可知道原因了,那怎么把文字移动过去呢?这边我们用 text-indent , 样式如下:
div{
width: 200px;
height: 200px;
border:10px solid rgb(255, 0, 0);
padding:15px;
margin:12px;
background-color: green;
text-indent: -20px;
}

效果如下:

从运行效果就可以看了,文字是在 border 上面的,所以文字区域(内联元素)是更靠近用户的
那如果 div 里面还有一个 div 呢?代码结构如下:
// html
<div class=”parent”>
你好,CSS 世界
<div class=”child”></div>
</div>
// css
.parent{
width: 200px;
height: 200px;
border:10px solid rgb(255, 0, 0);
padding:15px;
margin:12px;
background-color: green;
text-indent: -20px;
}
.child{
height: 20px;
background:purple;
}
效果如下:

又引发了一个问题,紫色区域是比文字区域高还是相反呢?
那怎么验证这个问题了?我们只要把里面的 div 往上移动就行,注意这里不能用 position 因为为改变层级结构,我们只要用 margin-top 就行了,如:
margin-top:-20px;
效果如下:

你会发现文字区域是在上面的。这边就得出一个结论:
如果 div 里面有块级元素,块级元素是盖不住内联元素的,换句话说内联元素离用户更近
那如果里面 div 有文字呢?这时我们需要 写几个字,效果如下:

你会发现 子元素的文字区域会盖住父元素的文字区域,所以这边又有一个小的结论:文字区域后出现的会覆盖前出现的。
浮动元素
来一个基本结构:
// html
<div class=”parent”>
你好
<div class=”float”>

</div>
</div>
// css
.parent{
width: 200px;
height: 200px;
border:10px solid rgb(255, 0, 0);
padding:15px;
margin:12px;
background-color: green;
color: aliceblue;
}
.float{
height: 40px;
width: 40px;
background:purple;
float: left;
}

效果如下:

上面代码就不解释了,你们肯定都 知道?按上面的套路,这里同样还是那个问题:你好在上面呢还是这个 float 元素呢?
要验证这个问题,同样使用 text-indent 那文字向左动点,这里我直接 上效果了:

从效果图,我们可以得出 文字区域是在 浮云元素上面的。
那浮动元素是在 文字区域与内部块级元素之间呢,还是内部块级与 border 元素之间呢?换句话说就是 浮动元素与块级元素哪个离用户更近?
我们直接在父级元素写一个 child:
// hmtl
<div class=”parent”>
你好
<div class=”float”></div>
<div class=”child”></div>
</div>

// css

.child{
height: 20px;
background: black;
}

效果如下:

从上可以看出浮云元素盖住了 child 元素,说明浮动元素的层级是比块级元素高的。即浮动元素是在文字区域与块级元素之间的。
那浮动元素里面的文字与外面的文字是怎么样的呢?这边我直接在浮动里面加了 float 文字,效果如下:

你会发现 浮动里面的文字是盖不住浮动外面文字的。
绝对定位元素
在上面的基础上我们增加一个 relative 元素,如下:
// htmk
<div class=”parent”>
你好
<div class=”float”>floatt</div>
<div class=”child”></div>
<div class=”relative”></div>
</div>

// css
.relative{
width: 100px;
height: 100px;
background: pink;
margin-top: -15px;
}

效果如下:

这时我们给类 relative 加上一个:
position:relative;

效果如下:

你会发现 relative 元素盖住了浮动元素,这说明 给元素加一个 relative 定位会增加对应的一个层级。检查 relative 元素,会看到:

加了 position:relative 定位会多了一个 z-index:auto 的东西,实际上你定位,都是按 z -index 来计算的。
这里我们给没有定位的 child 元素加上一个 z -index:
<div class=”parent”>
你好
<div class=”float”>floatt</div>
<div class=”child” style=”z-index:99999″></div>
<div class=”relative”></div>
</div>

效果如下:

你会发现 child 元素并没有盖住 relative 元素!
这边直接 给了结论了:z-index 只有在 position:relative|absolute 才有效果,如果都是 relative,z-index 一样,那么后面会盖前面,z-index 值大的会盖住小的。
我们接着在原有上加一个 relative2,样式如下:
.relative2{
width: 100px;
height: 150px;
background: gold;
margin-top: -15px;
position: relative;
}
效果如下:

此时给 relative2 加上一个 z-index:-1, 在看

又得出一个结论:z-index 为负值时,是位于 background 下面的
这时,我们给.parent 元素添加以下两个样式:
position: relative;
z-index: 0;

这时的效果如下:

这时奇怪的事情就出现了,z-index: -1 的跑到上面来了。
MDN 上有对什么堆叠给出了一些内容,如下:

其实我们给.parent 元素设置 z -index:0,根据 MDN 说的,我们其实已经 创造一个层叠上下文。
那什么是堆叠上下文?下面是张鑫旭一段原文:

其实这跟美国一个大法官说的一句话很像:我不知道什么色情,但当我看到它是我就知道什么是色情。
CSS 堆叠上下文也是类似的道理,你很难说出什么是 CSS 堆叠上下文,但只要它满足 MDN 列出的几种情况,它就是 CSS 堆叠上下文。
CSS 堆叠层叠顺序
CSS 堆叠上下文是有一个垂直屏幕上有一个上关系的,它们的关系如下:

所以这就解释为什么 z -index 为负值的时候,它会在 background 上面,因为我们 z-index:0 时就创建一个 CSS 堆叠上下文。
CSS 堆叠上下文作用
下面给一个基本的内容:
// html
<div class=”parent”>
<div class=”a relative”>a
<div class=”a1″>a1</div>
</div>
<div class=”b relative”>b
<div class=”b1″>b1</div>
</div>
</div>
// css
.parent{
width: 200px;
height: 200px;
border:10px solid rgb(255, 0, 0);
padding:15px;
margin:12px;
background-color: green;
}
.relative{
width:100px;
height:100px;
background: orange;
position: relative;
border:1px solid red;
}
.a1{
position: relative;
background:green;
}
.b1{
position: relative;
background:red;
}

效果如下:

接着我们在 b1 在添加以下样式:
margin-top: -90px;

b1 会盖住 a1,这个我们应该知道是什么原因了吧?因为 a1 b1 都是块级元素,后面会盖住前面的,没毛病!
那么 a1 和 b1 的 CSS 堆叠上下文是谁?
我们可以 MDN 给出的第一句:

根元素,所以 a1 和 b1 的 CSS 堆叠上下文就是 Html
接着给 a1 以下样式:
z-index: 2;

接着给 b1 以下样式:
z-index: 0;

效果如下:

a1 跑到 b1 上面了,这个很好理解,因为 a1 的 z -index:2 比 b1 的 z -index:0 在,所以 a1 在上面。
现在有一个问题,a1 是永远盖住 b1 吗?
这边你可能会说,a1 的 z -index:2 比 b1 的 z-index:0 永远都大,当然会盖住 b1 呀!是这样吗?我们试着改变一下 CSS 堆叠上下文。
我们分别给 a 和 b 各做一个 CSS 堆叠上下文:如下:
.a{
position: relative;
z-index: 1;
}
.b{
position: relative;
z-index: 1;
}

效果如下:

先分析 a 和 b 它们是谁覆盖谁,因为 两个定位和 z -index 都一样所以 b 会覆盖 a。还有一个现象有没有发现,b1 盖住了 a1? 明明 a1 的 z-index 大于 b1, 这是为什么?为什么小的会盖住大的?为什么?
因为 b 比 a 高一点,所以 b 里面的内容都会比 a 高一点。这就是 CSS 堆叠上下文一个特性。
比如说阿里巴巴有一个奇怪的部门叫做政委,是由马云等一些创始人组成的。在这个部门里面,你是不是都比其它部门要高级点。
所以 b1 虽然在 b 里面等级为 0,在 b 是高级的一个部门,就是可以压过你 a 这个部门里面的 2 级的人。
今天说这些了,如果还太明白可以看看以下的内容:
张鑫旭的深入理解 CSS 中的层叠上下文和层叠顺序 MDN 文档
更多内容可以关注下面这个很少人喜欢的一个笨笨的人
一个笨笨的码农,我的世界只能终身学习

退出移动版