Z-index研究 opacity和z-index一起使用

 

关于z-index的真正问题是,很少有人理解它到底是怎么用。其实它并不复杂,但是如果你从来没有花一定时间去看具体的z-index相关文档,那么你很可能会忽略一些重要的信息。

不相信我吗?好吧,看看你能否解决下面这个问题:

问题:

在 接下来的HTML里 有三个<div>元素,并且每个<div>里包含一个<span>元素。每 个<span>被分别给定一个背景颜色:红、绿、蓝。每个<span>被放置到文档的左上角附近,部分重叠着其他 的<span>元素,这样你就可以看到哪些是被堆叠在前面。第一个<span>有一个z-index的值为1,而其他两个没有任 何z-index值。

以下就是这个HTML和它的基本CSS。

HTML代码

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  1. <div>
  2. <span>Red</span>
  3. </div>
  4. <div>
  5. <span>Green</span>
  6. </div>
  7. <div>
  8. <span>Blue</span>
  9. </div>

CSS代码

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  1. .red, .green, .blue {
  2. position: absolute;
  3. }
  4. .red {
  5. background: red;
  6. z-index: 1;
  7. }
  8. .green {
  9. background: green;
  10. }
  11. .blue {
  12. background: blue;
  13. }

挑战:

尝试使红色<span>元素堆在蓝色和绿色<span>的后面,不要打破以下规则:

  • 不要以任何方式改变HTML标记
  • 不要添加/修改任何元素的z-index属性
  • 不要添加/修改任何元素的position属性

如果你找到了答案,那么它应该像下面这样:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  1. <div>
  2. <span>Red</span>
  3. </div>
  4. <div>
  5. <span>Green</span>
  6. </div>
  7. <div>
  8. <span>Blue</span>
  9. </div>
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  1. div:first-child {
  2. opacity: .99;
  3. }
  4. .red, .green, .blue {
  5. position: absolute;
  6. }
  7. .red {
  8. background: red;
  9. z-index: 1;
  10. }
  11. .green {
  12. background: green;
  13. }
  14. .blue {
  15. background: blue;
  16. }

解决方案:

这个解决方法是在第一个<div>里(红色<span>的父节点)添加一个小于1的opacity属性值。下面就是被添加的CSS的例子:

  1. 1
  2. 2
  3. 3
  1. div:first-child {
  2. opacity: .99;
  3. }

如果你现在很震惊,但是仍然百思不得其解,并且不相信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开发的可预测性。所以,让我们打破顺序,分解为独立的堆栈上下文。

在同样的堆栈上下文里的堆栈顺序

下面是几条基本的规则,来决定在一个单独的堆栈上下文里的堆栈顺序(从后向前):

  1. 堆栈上下文的根元素
  2. 定位元素(和他们的子元素)带着负数的z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)
  3. 非定位元素(按照在HTML中出现的顺序排序)
  4. 定位元素(和他们的子元素)带着auto的z-index值(按照在HTML中出现的顺序排序)
  5. 定位元素(和他们的子元素)带着正z-index值(高的值被堆叠在低值的前面;相同值的元素按照在HTML中出现的顺序堆叠)

注 解:定位元素带有负的z-index值被在一个堆栈上下文中先排序,这意味着他们出现在所有其他元素的后面。正因如此,它使一个元素出现在自己父元素之后 成为可能,这以前通常是不可能的事。当然,这局限于它的父元素与它在同一个堆栈上下文,并且不是那个堆栈上下文的根元素。一个伟大的例子如Nicolas Gallagher的CSS不用图像降低阴影

全局堆栈顺序

坚定的理解了为什么/什么时候新的堆栈上下文形成,同时掌握了同一个堆栈上下文的堆栈顺序,现在让你来找出一个特定元素将出现在全局堆栈里的顺序不是那么糟糕了吧?

避免错误的关键是能够发现新的堆栈上下文什么时候形成。如果你对一个元素设置了z-index值为十亿但是它没有在堆栈顺序中向前移动,检查一下它的祖先树,看是否它的父节点形成了堆栈上下文。如果是那样的话,你的z-index值即使有十亿也不会给你带来好处。

包扎救治

回到之前的原始问题,我已经重建了这个HTML的结构,添加了一些注释,每一个标签指明了它在堆栈里的顺序。这个顺序是假设最初的CSS。

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  1. <div><!-- 1 -->
  2. <span><!-- 6 --></span>
  3. </div>
  4. <div><!-- 2 -->
  5. <span><!-- 4 --><span>
  6. </div>
  7. <div><!-- 3 -->
  8. <span><!-- 5 --></span>
  9. </div>

当我们添加opacity到第一个<div>,堆栈顺序像下面这样改变:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  1. <div><!-- 1 -->
  2. <span><!-- 1.1 --></span>
  3. </div>
  4. <div><!-- 2 -->
  5. <span><!-- 4 --><span>
  6. </div>
  7. <div><!-- 3 -->
  8. <span><!-- 5 --></span>
  9. </div>

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研究 opacity和z-index一起使用的更多相关文章

  1. Index on DB2 for z/OS: DB2 for z/OS 的索引

    可以创建在任何表上的索引: Unique Index:An index that ensures that the value in a particular column or set of col ...

  2. git “bad index file sha1 signature fatal: index file corrupt”错误

    在执行commit或revert等操作时,提示“bad index file sha1 signature fatal: index file corrupt”错误,导致操作失败.这是由于git的in ...

  3. MySQL执行计划extra中的using index 和 using where using index 的区别

    本文出处:http://www.cnblogs.com/wy123/p/7366486.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  4. Elasticsearch之索引模板index template与索引别名index alias

    为什么需要索引模板? 在实际工作中针对一批大量数据存储的时候需要使用多个索引库,如果手工指定每个索引库的配置信息(settings和mappings)的话就很麻烦了. 所以,这个时候,就存在创建索引模 ...

  5. 聚簇索引(Clustered Index)和非聚簇索引 (Non- Clustered Index)

    本文转自https://my.oschina.net/u/1866821/blog/297673 索引的重要性数据库性能优化中索引绝对是一个重量级的因素,可以说,索引使用不当,其它优化措施将毫无意义. ...

  6. 重建索引:ALTER INDEX..REBUILD ONLINE vs ALTER INDEX..REBUILD

    什么时候需要重建索引 1. 删除的空间没有重用,导致 索引出现碎片 2. 删除大量的表数据后,空间没有重用,导致 索引"虚高" 3.索引的 clustering_facto 和表不 ...

  7. werkzeug.routing.BuildError: Could not build url for endpoint 'index'. Did you mean 'user.index' instead?

    werkzeug.routing.BuildError: Could not build url for endpoint 'index'. Did you mean 'user.index' ins ...

  8. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字符不改变,给定函数,编写函数 void Stringchang(const char*input,char*output)其中input是输入字符串,output是输出字符串

    import java.util.Scanner; /*** * 1. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字 ...

  9. MySQL explain结果Extra中"Using Index"与"Using where; Using index"区别探究

    问题背景 最近用explain命令分析查询sql执行计划,时而能看到Extra中显示为"Using index"或者"Using where; Using Index&q ...

随机推荐

  1. TestCase / test plan / test case

    s 测试计划 分析测试需求 制定测试策略 制定测试计划 评审测试计划 测试准备 编写测试案例 评审测试案例 准备测试环境 准备测试数据 准备配置项 测试执行 检查测试准入(环境.数据.配置.案例等) ...

  2. python---web框架本质(1)

    总的来说php相对较为简单,但是内部封装太多,不利于对编程的更本质探索. 但是对于生产开发确实是一门不错的语言.python对于socket以及web框架的理解更加透彻 # coding:utf8 # ...

  3. CodeForces - 327D Block Tower

    D. Block Tower time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  4. Django 2.0.1 官方文档翻译:编写你的第一个djang补丁(page 15)

    编写你的第一个djang补丁(page 15) 介绍 有兴趣为社区做一些贡献?可能你发现了django中的一个你想修复的bug,或者你你想添加一个小小的功能. 回馈django就是解决你遇到的问题的最 ...

  5. 去除inline-block出现间距的几种方法

    display:inline-block,简单来说就是将对象呈现为inline对象,但是对象的内容作为block对象呈现,之后的内联对象会排列在同一行 比如两个input,默认中间会产生一些间距 &l ...

  6. C# 生成一个带数字的饼图

    using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D ...

  7. MyBatis全局配置文件mybatis-config.xml

    1.在官方下载的mybatis-3.4.5.zip压缩包中,有我们需要的mybatis核心jar包和mybatis的快速入门的pdf文件 在mybatis的快速入门的pdf文件中,复制如下代码到我们项 ...

  8. dijkstra补充

    dijkstra主要写法: priority_queue<pair<int,int> >q; //大根堆 //dis第一维为dis的相反数 void dijkstra(){ m ...

  9. C++ 中 #ifndef, #define, #endif 宏定义

    目的:为了保证包含的内容只被程序(include) 和编译了一次.判断预处理器常量是否已被定义. 预编译将所有头文件(#include"XXX.h")用头文件中的内容来替换,头文件 ...

  10. Docker入门02——Dockerfile详解

    基本示例 FROM MAINTAINER LABEL RUN ADD COPY CMD ENTRYPOINT ENV EXPOSE VOLUME WORKDIR USER ARG 基本示例 # Thi ...