一篇通俗易懂的CSS层叠顺序与层叠上下文研究
网上有很多这方面的教程,但不是苦涩难懂就是从哪copy过来的,反正很长一段时间我是没看懂,时间长了也没打算去研究了,主要原因是,基本上很少会遇到那些问题(所以说啊,要是没有研究精神的才懒得管它)。但自从开始研究CSS以后就一发不可收拾,所以打算把CSS一系列的东西都给研究一遍,当然能研究懂自然是好的,不能就当自娱自乐了。话说这个层叠顺序和堆栈上下文没啥用对吧,你看我就是不学它,平时也没出什么问题。 …… 想让它出问题也很简单,不过既然你都说没用了,也就不打算告诉你了。
本篇属于短话长说型,前半部分比较简单,但不看会影响后面你是否有勇气看下去,建议全看,但如只是想了解一下,可以只看总结部分,但都看你自己。
层叠顺序和层叠上下文是两个概念,但它们又有着密不可分的关系,层叠顺序很简单^_^,认真思考即可,而堆栈上下文更是不值一提,我只需要迁根红线你就懂了,所有说,都太简单。第一段说难懂,主要是有了这篇文章,才化解位移。废话少说,看剑。
在考虑到两个元素可能重合的情况下,W3C提出了层叠这个概念,层叠是指如何去层叠另一个元素,比如两个元素重合的时候应该让谁在前面,谁在后面。那它们的规则又是什么?先来试水。
层叠顺序篇
当两个元素都是块级元素时,默认情况越后面的元素层级越高
<style>
div{ width:100px; height:100px;
} .item1{ color:red; background-color:pink;
} .item2{ margin-top:-100px; background-color:orange;
}</style><div class="item1">item11111</div><div class="item2">item22222</div>
可以看到item2
把item1
给盖住了,说明越后面的元素层级越高,另外item1
的文字还是隐隐约约的可以看到,这说明了背景的层级比文字小。
另外我们可以这样
<style>
div{ width:100px; height:100px;
} .item1{ color:red;
} .item2{ margin-top:-100px;
}</style><div class="item1">item11111</div><div class="item2"></div>
可以看到好像没有item2这个元素一样,主要原因是,在没有设置背景的情况下,元素的背景是透明的(transparent),并且允许后面的元素透上来。
在这种条件下,你会发现一个很搞笑的事,如下:
<style>
div{ width:100px; height:100px;
} .item1{ color:red;
} .item2{ background-color:orange; margin-top:-100px;
}</style><div class="item1">我是item2</div><div class="item2"></div>
如果不看代码,就好像这段代码真的是item2
的。
当两个元素为行内块时
<style>
div{ display:inline-block; width:100px; height:100px;
} .item1{ background-color:pink;
} .item2{ background-color:orange; margin-left:-108px;
}</style><div class="item1">item1111</div><div class="item2">item2</div>
也是后一个元素的层级比前一个元素的层级高,不过和两个块级元素不同的是行内块元素的背景层级比文字高。
当两个元素为行内元素时
<style>
div{ display:inline; width:100px; height:100px;
} .item1{ background-color:pink;
} .item2{ margin-left:-48px; background-color:orange;
}</style><div class="item1">item1</div><div class="item2">item2</div>
和行内块的行为一样,背景层级比文字高,并且也是后一个元素比前一个元素层级高。
小总结
- 当两个元素为正常流时,默认情况下后一个元素比前一个元素层级高,并且允许后面的元素透上来。
- 如果两个元素是块级元素,文字比背景层级高(因此不管是否设置背景文字始终会透上来)。
- 如果是行内或行内块,背景比文字层级高(因此只要设置背景,后一个元素将透不上来)。
当一个元素为块级元素,另一个为行内块时
<style>
div{ width:100px; height:100px;
} .item1{ display:inline-block; background-color:pink;
} .item2{ margin-top:-100px; background-color:orange;
}</style><div class="item1">item1</div><div class="item2">item2</div>
行内块比块级元素层级高,依然是文字比背景层级高。
如果另外一个元素是行内元素和这个效果也是一样的,代码如下:
<style>
div{ width:100px; height:100px;
} .item1{ display:inline; background-color:pink;
} .item2{ margin-top:-30px; background-color:orange;
}</style><div class="item1">item1</div><div class="item2">item2</div>
当一个元素是行内块另一个是行内元素时
<style>
div{ width:100px; height:100px;
} .item1{ display:inline-block; background-color:pink;
} .item2{ display:inline; margin-left:-100px; background-color:orange;
}</style><div class="item1">item1</div><div class="item2">item2</div>
行内元素层级比行内块元素高,背景比文字层级高。
浮动系列
- 浮动和浮动,后一个比前一个层级高。
- 浮动和块元素,浮动层级高。
- 浮动和行内块,行内块层级高。
- 浮动和行内,行内层级高。
效果如下:
定位系列
- 绝对定位和绝对定位,后一个比前一个层级高。
- 绝对定位和相对定位,后一个比前一个层级高。
- 绝对定位和固定定位,后一个比前一个层级高。
- 固定定位和相对定位,后一个比前一个层级高。
- 绝对定位和块元素,绝对定位层级高。
- 决定定位和行内块,绝对定位层级高。
- 绝对定位和行内元素,绝对定位层级高。
- 绝对定位和浮动,绝对定位层级高。
- 其他定位和绝对定位效果一样。
层叠顺序总结
- 当两个元素类型一样时,默认情况下后一个元素层级比前一个元素层级高。
- 在没有设置背景的情况下,元素的背景是透明的,并且允许后面的元素透上来。
- 块元素和其他任意除定位元素以外,文字层级比背景层级高。
- 浮动和块元素,浮动层级高。
- 浮动和行内块,行内块层级高。
- 浮动和行内,行内层级高。
- 定位和定位,后一个元素层级高。
- 定位比所有元素层级高。
它们的前后顺序:小于0的z-index < 块 < 浮动 < 行内块 < 行内 < 定位 < 大于0的z-index
层叠上下文
如果你认真看完上一节,会不会奇怪一个问题,那就是在无特殊情况下为什么定位元素总是比普通元素层级高,另外一点就是,大部分情况下为什么总是后一个元素比前一个元素层级高,而罪魁祸首就是层叠上下文。
在HTML中有一个三维概念,也就是我们面向电脑屏幕的这一端为Z轴。
而凡是拥有层叠上下文的元素,将离用户最近,也就是越靠在Z轴前面。默认情况下只有根元素HTML
会产生一个层叠上下文,并且元素一旦使用了一些属性也将会产生一个层叠上下文,如我们常用的定位属性。如两个层叠上下文相遇时,总是后一个层叠前一个,除非使用z-index来改变。如下:
<style>
.box1{ width:100px; height:100px; background-color:red;
} .box1 .item{ position:relative; height:100px;
} .box2{ margin-top:-50px; width:100px; height:100px; background-color:orange;
}</style><div class="box1">box1 <div class="item"></div></div><div class="box2">box2</div>
虽然item产生了一个层叠上下文,但并不影响它父元素。它的父元素依然被box2层叠了。另外上面还说只要是产生层叠上下文的元素总是比其他元素层高,如下:
只需要给item加上一个背景即可,上一个案例只所以没看到item元素是因为背景默认是透明的,并且允许后面的元素透上来。
除了定位元素可以创建层叠上下文以外,还有如下几个属性也可以做到。以下来自MDN
- 根元素 (HTML),
- z-index 值不为 "auto"的 绝对/相对定位,
- 一个 z-index 值不为 "auto"的 flex 项目 (flex item),即:父元素 display: flex|inline-flex,
- opacity 属性值小于 1 的元素
- transform 属性值不为 "none"的元素,
- mix-blend-mode 属性值不为 "normal"的元素,
- filter值不为“none”的元素,
- perspective值不为“none”的元素,
- isolation 属性被设置为 "isolate"的元素,
- position: fixed
- 在 will-change 中指定了任意 CSS 属性,即便你没有直接指定这些属性的值
- -webkit-overflow-scrolling 属性被设置 "touch"的元素
这里再拿opacity试水。
代码如下:
<style>
.box1{ opacity:.9; width:100px; height:100px; background-color:red;
} .box2{ margin-top:-50px; width:100px; height:100px; background-color:orange;
}</style><div class="box1">opacity</div><div class="box2">box2</div>
原本应该是box2层叠box1的,但因为box1创建了一个层叠上下文,所以把box2层叠了。
总结
- 创建了层叠上下文的元素比其他元素层级高。
- 两个层叠上下文相遇时,后一个层级高。如果想改变层级可以使用z-index
- Python进阶学习之阅读代码
- 代码安全审计:当file_exists遇上eval
- Python 异常处理完整指南
- 有趣的安全实验:利用多线程资源竞争技术上传shell
- NotSerializableException解决方法NotSerializableException
- 谁蹭了我的WiFi?浅谈家用无线路由器攻防
- 当输入流和输出流同时作用一个文件
- 揭秘:充电宝是如何盗取你的个人隐私的?
- 微软:暴力破解面前,增强密码复杂性基本没用
- 创建被图像填充的组件解释几处做法解释几点
- Android原生嵌入React Native
- React Native控件之Listview
- React Native控件只TextInput
- Qzone React Native改造
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例
- crictl调试Kubernetes节点
- leetcode哈希表之好数对的数目
- Python处理excel的强大工具-openpyxl
- Pycharm最高效的快捷键集合
- 关于Python循环,看这一篇就够了
- Python新手常见错误汇总|附代码检查清单
- 入门快速安装ElasticSearch
- Kubernetes强制删除Terminating的ns
- 如何使用慢查询快速定位执行慢的 SQL?
- 前端路由实现原理
- 模拟虚拟dom生成实际dom
- Promise教程之产房里生孩子的故事
- 一个现实生活中的例子让你理解Promise的使用场景
- react 跨级组件传参方式 context方式的传参
- Excel文件导入导出操作