z-index
这个属性表面看上去很简单,但如果你想搞清楚其工作原理的话,其实是有不少值得探讨之处的。本文将从层叠上下文(stacking contexts)和一些实际案例出发,谈一谈 z-index
的内部工作原理。
CSS 为盒模型的布局提供了三种不同的定位方案[1] :
最后一种方案(特指绝对定位)将会把元素从正常文档流中完全移走,其最终的落脚点将取决于开发者。
通过设置 top
,left
,bottom
和 right
的值,你可以在二维空间中对元素进行定位,但 CSS 同时也允许你使用 z-index 属性[2] 把它放置在三维空间中。
表面看起来,z-index
似乎是一个很简单的属性,你给它设置哪个值,元素就会位于 y 轴的哪个位置,就这样。但它实际上并没有我们想象的这么简单,这个属性背后是一系列决定元素所在层级的规则。
为了保证我们在同一个“频道”上,这里我先普及一些基础概念,之后再解释层叠的相关知识,并在一些场景中体会 z-index[3] 作用的机制。
对于三维空间坐标系,你肯定很熟悉了。x 轴代表水平方向,y 轴代表垂直方向,z 轴则代表我们的目光向页面(屏幕)看进去的时候,各元素的布局情况。
由于屏幕是一块二维平面,我们实际上并没有真的看到 z 轴,更多的是通过透视的形式。具体地说,多个元素共享同一块二维平面时,有的元素在顶部,有的元素在底部,我们由此感受到了 z 轴的存在。
为了决定某个元素在 z 轴方向上的位置,CSS 允许我们为 z-index 属性设置三种值[4]:
我们主要看一下整数值。它可以是正整数、负整数或者 0,值越大,元素就离我们“越近”,值越小,元素自然也就离我们“越远”。
如果两个元素在定位之后共享同一块二维空间,那么在这块空间中, z-index
越大的元素将可能覆盖 z-index
较小的元素。
很显然,上面讲的这些都是非常容易理解的,并且也和我们的直觉相符合。不过,下面的问题恐怕就不是很好回答了:
z-index
的元素与一个位于正常文档流中的元素重叠时,哪一个在顶层呢?为了更好地理清这些问题,我们有必要进一步理解与 z-index
工作原理相关的一些概念,也就是层叠上下文、层叠等级和层叠顺序。
针对层叠上下文和层叠等级[5] ,可能很难给出一个清晰易懂的概念,所以我们这里用通俗的例子来理解。想象一下,现在有一张桌子,上面摆满了各种东西。那么这张桌子就代表了一个层叠上下文,假设还有另一张与之并排的桌子,那么就产生了另一个层叠上下文。
如图所示,层叠上下文 1 指的就是文档根部,而层叠上下文 2 和 3 位于 1 的某个层叠等级中。此外,这两个层叠上下文各自会包含新的层叠等级。
现在想象一下,第一张桌子上面并排摆了四个砖头,这四个砖头上面放着一个玻璃杯,而玻璃杯上面还放着一个水果盘。那么,砖头、玻璃杯、水果盘,各自都处于不同的层叠等级中,但它们共处于“桌子”这一层叠上下文中。
对每一个网页来说,默认都会创建一个层叠上下文[6] ,这个上下文(这张桌子)的根部就是 html
元素,html
元素的所有子元素都会位于这个默认的层叠上下文中的某个层叠等级,就好比东西会摆放在桌子的不同位置上一样。
当你给某个元素设置一个非 auto
的 z-index
时,就会创建一个新的 层叠上下文[7] ,它和它所包含的层叠等级都是独立于其它层叠上下文和层叠等级的,就好比你搬了一张新的桌子放在房间里,它和旧的桌子是互相独立的。
我们可以通过一个非常简单的例子来理解层叠顺序,这个例子甚至还不需要涉及到 定位元素[8] 。
想象一下,现在有一个非常简单的网页,不考虑默认的 <html>
, <head>
, <body>
等元素,就只需要考虑每个网页至少都会有的一个 <div>
。在 CSS 文件中设置 html
的背景颜色为蓝色,设置 div
的背景颜色为红色,并设置宽高。
当加载页面的时候,你觉得会看到什么?
这个自然不用多想,引入眼帘的肯定是一大片的蓝色,同时还有一个此前设置好尺寸的红色块级元素。除非你做了额外的设置,否则这个元素将正常地出现在左上角。
你可能会说“就这?太简单了吧”,不过有一个问题可能不那么简单:为什么红色的块级元素就一定会位于蓝色背景的上层呢?为什么我们看到的就是 div
位于 html
的上层呢?原因是,它们都遵循了层叠顺序的规则。
在这个简单的例子中,根据规则,正常文档流的子块(div
)的层级将会高于根元素(html
)的背景和边框。我们看到div
位于顶层,这是因为它的层叠等级更高。
虽然上面这个例子只涉及到了两个层叠等级,但实际上,在一个层叠上下文中,一共可能出现七个层叠等级,从最低到最高排列,依次是:
z-index
为负数的子元素以及由它所产生的层叠上下文z-index
为 0 的、定位的子元素以及由它所产生的层叠上下文z-index
为正数的、定位的子元素以及由它所产生的层叠上下文,它是整个上下文中层叠等级最高的这七个层叠等级就构成了层叠顺序的规则。符合层叠等级七的元素,会比层叠等级在一到六的元素更“贴近我们”,符合层叠等级五的元素,会比层叠等级二的元素更“贴近我们”,以此类推。
第一次学习这些层叠规则的时候,我感觉收获了很多新的东西。如果只着眼于层叠等级二、六和七(也就是涉及到 z-index
的等级),那么大部分时候,我们对于 z-index
的理解是正确的。正的 z-index
的层级比 0 要高,而 0 又比负的要高,一切都符合直觉,可能大多数人到这里就不继续往后探究了。
我之前就是这样,在看到这些规则之前,以为除了正的和负的 z-index
,其它情况都可以看作是 z-index
为0 —— 不过现在我们很清楚了,这种想法是错误的。事实是,大部分元素的层级都要低于 z-index:0
。
还有一个有趣的细节是,非定位的元素实际位于四种不同的层叠等级中。乍一想觉得很奇怪,不过其实这是很合理的。假设所有的非定位元素都位于同一个层叠等级,那么我们就没办法在 div
(块级盒)上看到文本(内联盒)了。
我前面提到过很多次,当你给一个元素设置非 auto 的 z-inde
时,会创建一个新的、完全独立的层叠上下文。
重新回顾一下之前拿桌子做比喻的案例。一开始的时候,我们的桌子上摆满了四块砖头,上面是一个玻璃杯,再上面是一个水果盘。现在,假设又有一张新的桌子,它摆放的东西和旧桌子差不多,唯一的不同是,新桌子少了一个水果盘。
不难想象,旧桌子的水果盘是整个房间中位于最顶层的物品(它有最大的 z-index
),不过,如果把旧桌子以及它上面的所有东西整体搬到地下室呢?此时,水果盘的层级会比新桌子上的每一个物品都要低,这是因为,放置水果盘的旧桌子整体已经低于新桌子了。
对于网页上的定位元素来说,其实道理是一样的。假设有如下代码,思考一个问题:div.two
和 div.four
,哪个在上哪个在下?
HTML:
<div class="one">
<div class="two"></div>
<div class="three"></div>
</div>
<div class="four"></div>
CSS:
div {
width: 200px;
height: 200px;
padding: 20px;
}
.one, .two, .three, .four {
position: absolute;
}
.one {
background: #f00;
outline: 5px solid #000;
top: 100px;
left: 200px;
z-index: 10;
}
.two {
background: #0f0;
outline: 5px solid #000;
top: 50px;
left: 75px;
z-index: 100;
}
.three {
background: #0ff;
outline: 5px solid #000;
top: 125px;
left: 25px;
z-index: 150;
}
.four {
background: #00f;
outline: 5px solid #ff0;
top: 200px;
left: 350px;
z-index: 50;
}
尽管 div.two
有更高的 z-index
(100),但在页面上,它的层级实际上比 div.four
(z-index
为50)要低。下图就是页面元素的层级情况,根据黑色和黄色边框,我们可以区分每个元素生成的不同的层叠上下文。
由于 div.two
位于 div.one
中,所以它的 z-index
是和 div.one
的层叠上下文相关的,也就是说,实际表现出来的 z-index
是下面这样的:
div.one
和内部包含的一切将会在层级上低于 div.four
,无论给 div.one
的子元素设置多大的 z-index
,子元素的层级都无法超过 div.four
。
看到这个例子是不是有一种熟悉的味道?我也曾经被 z-index
这么坑过一两次。我们都曾疑惑一个问题,为什么一个 z-index
非常大的元素,在层级上始终无法超过一个 z-index
比它小很多的元素?相信在学习了这些案例之后,你已经豁然开朗了。
在最初学习 z-index
的时候,我们都会认为它很简单,这不就是代表元素在 z 轴上的位置吗?不过我们现在知道了,事情远没有这么简单。深入理解 z-index[9] 一文也揭示了 z-index
背后一些原理层面的东西,包括层叠上下文,层叠等级以及一系列决定元素的层叠顺序的规则。
最后,记住一个很重要的结论:定位元素可以创建新的层叠上下文,在这个上下文中的所有层叠等级,都会高于或者低于另一个层叠上下文的所有层叠等级。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/t7mgEFRkH6HDBCdjJUA2JA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。