关于z-index的那些事儿
关于z-index的真正问题是,很少有人理解它到底是怎么用。其实它并不复杂,但是如果你从来没有花一定时间去看具体的z-index相关文档,那么你很可能会忽略一些重要的信息。
不相信我吗?好吧,看看你能否解决下面这个问题:
问题:
在 接下来的HTML里 有三个<div>元素,并且每个<div>里包含一个<span>元素。每 个<span>被分别给定一个背景颜色:红、绿、蓝。每个<span>被放置到文档的左上角附近,部分重叠着其他 的<span>元素,这样你就可以看到哪些是被堆叠在前面。第一个<span>有一个z-index的值为1,而其他两个没有任 何z-index值。
以下就是这个HTML和它的基本CSS。
HTML代码
1 |
<div> |
CSS代码
1 |
.red, .green, .blue { |
挑战:
尝试使红色<span>元素堆在蓝色和绿色<span>的后面,不要打破以下规则:
- 不要以任何方式改变HTML标记
- 不要添加/修改任何元素的z-index属性
- 不要添加/修改任何元素的position属性
如果你找到了答案,那么它应该像下面这样:
1 |
<div> |
1 |
div:first-child { |
解决方案:
这个解决方法是在第一个<div>里(红色<span>的父节点)添加一个小于1的opacity属性值。下面就是被添加的CSS的例子:
1 |
div:first-child { |
如果你现在很震惊,但是仍然百思不得其解,并且不相信opacity能决定哪个元素堆在前面,欢迎来社区提问,当第一次在这个问题上被困扰时我同样很震惊。
希望接下来的内容能够让你对这个问题更清楚些。
堆栈顺序
Z-index看上去如此简单:高的z-index堆在低的z-index的前面,对吗?这实际上是错的,是z-index问题的一部分。它看上去如此的简单,以至于很多开发者没有花相应的时间去读相关的规则。
每一个在HTML文档中的元素既可以在其他元素的前面,也可以在其他元素的后面。这就是所谓的堆栈顺序。决定这个顺序的规则被十分清楚的定义在说明文档中,但是就像之前我已经提到过,这些文档没有被大多数开发者们完全弄明白。
当z-index和position属性不被包括在内时,这些规则相当简单:基本上,堆栈顺序和元素在HTML中出现的顺序一样。(好吧,其实是有一点复杂的,但是只要你不使用压缩边界来重叠行内元素,你可能不会遇到边界问题。)
当你把位置属性也包括在内介绍时,任何定位元素(和他们的子元素)都在非定位元素前被显示出来。(说一个元素被“定位”意思是它有一个不同于静态的位置值,例如相对的,绝对的,等等。)
最 后,当z-index被提及时,事情变的有点儿复杂。最初,很自然的假设带有高z-index值的元素会在带有低z-index值的元素前面,但是后来发 现没那么简单。首先,z-index只对定位元素起作用。如果你尝试对非定位元素设定一个z-index值,那么肯定不起作用。其次,z-index值能 创建堆栈上下文环境,并且突然发现看似简单的东西变的更加复杂了。
堆栈上下文
一组具有共同双亲的元素,按照堆栈顺序一起向前或向后移动构成了所谓的堆栈上下文。充分理解堆栈上下文是真正掌握z-index和堆栈顺序工作原理的关键。
每 一个堆栈上下文都有一个HTML元素作为它的根元素。当一个新的堆栈上下文在一个元素上形成,那么这个堆栈上下文会限制所有的子元素以堆栈的顺序存储在一 个特别的地方。那意味着一旦一个元素被包含在处于底部堆栈顺序的堆栈上下文中,那么就没有办法先出现于其他处于更高的堆栈顺序的不同堆栈上下文元素,就算 z-index值是十亿也不行!
现在,堆栈上下文有三种方法可以在一个元素上形成:
- 当一个元素是文档的根元素时(<html>元素)
- 当一个元素有一个position值而不是static,有一个z-index值而不是auto
- 当一个元素有一个opacity值小于1
前两种形成堆栈上下文的方法具有很大意义并且被广大Web开发者所理解(即使他们不知道这些被叫做什么)。第三种方法(opacity)几乎从来没在w3c说明文档之外被提及过。
用堆栈顺序决定一个元素的位置
实际上,为一个页面上的所有元素决定全局堆栈顺序(包括边界、背景、文本节点、等等)是极度复杂的,并且远远超越了本文讲述的范围(再一次,参考文档)。但是我们最大的目的,就是基本了解这个顺序,它能够在很长一段时间内帮助我们提高CSS开发的可预测性。所以,让我们打破顺序,分解为独立的堆栈上下文。
在同样的堆栈上下文里的堆栈顺序
下面是几条基本的规则,来决定在一个单独的堆栈上下文里的堆栈顺序(从后向前):
- 堆栈上下文的根元素
- 定位元素(和他们的子元素)带着负数的z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)
- 非定位元素(按照在HTML中出现的顺序排序)
- 定位元素(和他们的子元素)带着auto的z-index值(按照在HTML中出现的顺序排序)
- 定位元素(和他们的子元素)带着正z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)
注 解:定位元素带有负的z-index值被在一个堆栈上下文中先排序,这意味着他们出现在所有其他元素的后面。正因如此,它使一个元素出现在自己父元素之后 成为可能,这以前通常是不可能的事。当然,这局限于它的父元素与它在同一个堆栈上下文,并且不是那个堆栈上下文的根元素。一个伟大的例子如Nicolas Gallagher的CSS不用图像降低阴影。
全局堆栈顺序
坚定的理解了为什么/什么时候新的堆栈上下文形成,同时掌握了同一个堆栈上下文的堆栈顺序,现在让你来找出一个特定元素将出现在全局堆栈里的顺序不是那么糟糕了吧?
避免错误的关键是能够发现新的堆栈上下文什么时候形成。如果你对一个元素设置了z-index值为十亿但是它没有在堆栈顺序中向前移动,检查一下它的祖先树,看是否它的父节点形成了堆栈上下文。如果是那样的话,你的z-index值即使有十亿也不会给你带来好处。
包扎救治
回到之前的原始问题,我已经重建了这个HTML的结构,添加了一些注释,每一个标签指明了它在堆栈里的顺序。这个顺序是假设最初的CSS。
1 |
<div><!-- 1 --> |
当我们添加opacity到第一个<div>,堆栈顺序像下面这样改变:
1 |
<div><!-- 1 --> |
span.red曾经的顺序是6,但现在改为1.1。我已经使用“.”来标注一个新的上下文环境的形成。span.red现在是那个新的上下文的第一个元素。
现 在似乎更清晰了,关于为什么红色盒子跑到其他盒子的后面。原始的例子只包含两个堆栈上下文,根元素和形成span.red的那个。当我们添加 opacity到span.red的父节点上,形成了第三个堆栈上下文,结果显示在span.red上的z-index值只能应用在那个新的堆栈上下文 中。因为第一个<div>(应用opacity的那个)和它的兄弟元素没有position或者z-index值的集合,他们的堆栈顺序是由 他们在HTML里的源顺序决定的,也就是说第一个<div>,和它的堆栈上下文里的所有元素被第二个和第三个<div>元素分 离。
关于z-index的那些事儿的更多相关文章
- Shadow Map阴影贴图技术之探 【转】
这两天勉勉强强把一个shadowmap的demo做出来了.参考资料多,苦头可不少.Shadow Map技术是目前与Shadow Volume技术并行的传统阴影渲染技术,而且在游戏领域可谓占很大优势.本 ...
- 运用<div>布局页面练习
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 关于Cewu Lu等的《Combining Sketch and Tone for Pencil Drawing Production》一文铅笔画算法的理解和笔录。
相关论文的链接:Combining Sketch and Tone for Pencil Drawing Production 第一次看<Combining Sketch and Tone f ...
- 四种比较简单的图像显著性区域特征提取方法原理及实现-----> AC/HC/LC/FT。
laviewpbt 2014.8.4 编辑 Email:laviewpbt@sina.com QQ:33184777 最近闲来蛋痛,看了一些显著性检测的文章,只是简单的看看,并没有深入的研究,以 ...
- C# 金钱 小写转大写的算法
调用 ConvertMoney的ConvertMoneyToWords(decimal money)方法即可 using System; using System.Collections.Generi ...
- 【Unity3D】利用Shader以及更改Mesh实现2D游戏的动态阴影效果
最近看到一个非常有趣的益智小游戏,是一个盗贼进入房子偷东西的, 其实这种游戏市面上已经很多了,吸引我的是那个类似手电筒的效果, 主角走到哪里,光就到哪里,被挡住的地方还有阴影.有点类似策略游戏里的战争 ...
- 来看看css3中的box-shadow
不谈IE,只谈谈box-shadow的具体使用方法 语法: E {box-shadow: <length> <length> <length>?<length ...
- img和css背景的选择
在什么情况下更适合使用HTML IMG标签来显示一个图像,而不是一个CSS有背景图像,反之亦然? 如下场景使用img标签比较合适: 1.如果图像是等内容的一部分或图表或人(真正的人,而不是股票图人), ...
- 深入理解CSS中的层叠上下文和层叠顺序(转)
by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道 ...
- 2016 年青岛网络赛---Family View(AC自动机)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5880 Problem Description Steam is a digital distribut ...
随机推荐
- EOJ2018.10 月赛(B 数学+思维题)
传送门:Problem B https://www.cnblogs.com/violet-acmer/p/9739115.html 题意: 找到最小的包含子序列a的序列s,并且序列s是 p -莫干山序 ...
- ElasticSearch搜索介绍四
ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, &quo ...
- maven中修改可用的版本
一般情况下,我们都是建项目,写代码,然后再部署运行的.到最后因为版本问题无法部署的情况下怎么办?重新建项目,然后导代码,这太麻烦了. 一般的处理情况:在项目的硬盘目录中,找到.setting文件夹下的 ...
- Python基础【day03】:字符转编码操作(五)
本节内容 1.编码介绍 2.字符编码介绍 3.总结 说到python的编码,一句话总结,说多了都是泪啊,这个在以后的python的开发中绝对是一件令人头疼的事情.所以有必要要讲讲清楚 一.编码介绍 1 ...
- Unity NavMesh导航网格 初级教程
目的:要实现的功能就是你点击一下地图上的某个地方,人物就向着那个点移动.有点自动寻路的味道. 例子:三国群英传,三国赵云传之类的游戏里面的人物移动就可以用这个实现.还有一个我不太喜欢玩的游戏英雄联盟 ...
- 常用的Date对象和Math对象方法
Date对象方法: 当前用户本地时间 let time = new Date(); 获取整数年 console.log(time.getFullYear()); 获取当前月(月份要加1) consol ...
- ECSHOP /api/client/includes/lib_api.php
ecshop /api/client/api.php./api/client/includes/lib_api.php ECShop存在一个盲注漏洞,问题存在于/api/client/api.php文 ...
- Photoshop的辅助线
其它功能: 1.在拖动参考线时,按下Alt键能在垂直和水平参考线之间进行切换.按下Alt键,点击当前垂直的水平线就能够将其改变为一条水平的参考线,反之亦然. 2.按下Shift键拖动参考线能够强制它们 ...
- 调用write()写
一.在POSIX中的定义 #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 二.返回值 ( ...
- UpnP Hacking
1.概述 通用即插即用(UpnP)是一种用于PC机和智能设备的常见对等网络连接的体系结构. UPnP以Internet标准和技术(例如Tcp/IP.HTTP和XML)为基础,使这样的设备彼此可自动连接 ...