没人告诉你关于z-index的一些事
关于z-index的问题是很多程序员都不知道它是如何起作用的。说起来不难,但是大部分人并没有花时间去看规范,这往往会照成严重的后果。
你不信?那就一起来看看下面的问题。
问题
在下面的HTML我们写了3个<div>元素,然后每个<div>元素里面都有一个<span>元素,每个<span>元素都有个背景色,并且使用absolute定位,为了能更清楚地看到z-index的效果,我们写了一些其他的样式。第一个<span>元素的z-index值为1,其他两个没有设置。
代码如下:
<div>
<span class="red">Red</span>
</div>
<div>
<span class="green">Green</span>
</div>
<div>
<span class="blue">Blue</span>
</div>
.red, .green, .blue {
position: absolute;
}
.red {
background: red;
z-index: 1;
}
.green {
background: green;
}
.blue {
background: blue;
}
然后挑战来了: 尝试把红色的<span>元素放到其他两个元素后面,但是必须遵守下面的规则:
- 不能修改HTML的内容
- 不能增加或修改任何元素的
z-index属性 - 不能增加或修改任何元素的
position属性
想挑战一些的话,就点击上面Codepen的Edit按钮去尝试一下吧。如果你不能做到,那就接着看下去。
解决方案
解决方案很简单,你只需要给红色的<span>标签增加一个opacity小于1,像下面这样:
div:first-child {
opacity: .99;
}
如果你觉得不可思议了,不相信透明度会影响叠加顺序,那么恭喜你,即将学习新的技能,一开始看到我也不信。
接下来让我们来摸索一番。
堆叠顺序
z-index看上去很简单,z-index值大的元素在z-index值小的元素前面,对吧?但其实这只是z-index的一部分用法。很多程序猿都觉得很简单,没有花太多时间去认真阅读规则。
HTML中的每一元素都是在其他元素的前面或者后面。这是众所周知的堆叠顺序(Stacking Order),这条规则在w3c规范里面说的很清楚,但我前面提到过了,大部分程序猿并不真正理解。
如果没有涉及z-index和position属性的话,那规则很简单,堆叠顺序就是元素在HTML中出现的顺序。(当然如果你对行内元素使用负margin的话,可能情况会复杂一些。)
加上position属性的话,就是所有定位了得元素在没有被定位的元素前面。(一个元素被定位的意思这里指的是它有一个position属性,但是不是static,而是relative,absolute等)
再加上z-index属性,事情就变得有点诡异。首先z-index值越大,越靠前。但是z-index属性只作用在被定位了的元素上。所以如果你在一个没被定位的元素上使用z-index的话,是不会有效果的。还有就是z-index会创建一个堆叠的上下文(Stacking Contexts),我们可以理解为一个层。
堆叠上下文
同一个父元素下面的元素会受父元素的堆叠顺序影响,所以堆叠上下文是我们理解z-index和堆叠顺序的关键。(下面为了简化,我们称堆叠上下文为层。)
每一个层都有唯一的根节点。当一个元素创建一个层,那么它的所有子元素都会受到父元素的堆叠顺序影响。意味着如果一个元素位于一个最低位置的层,那你z-index设置得再大,它也不会出现在其它层元素的上面。
现在我们来说说什么情况下会产生新的层:
- 当一个元素位于HTML文档的最外层(
<html>元素) - 当一个元素被定位了并且拥有一个
z-index值(不为auto) - 当一个元素被设置了
opacity,transforms,filters,css-regions,paged media等属性。
一二条规则,Web开发者都知道,虽然他们不一定知道怎么描述
最后一条,是很多非w3c规范里面的文章很少提到的。通常来讲,如果一个CSS属性需要做一些特效的话,它都会创建一个新的层。
影响堆叠顺序的因素有很多,我推荐你去看w3c规范,这篇文章我们主要探讨关于层的内容。
同一层里面的堆叠顺序
下面是同一层里面的堆叠顺序(从后到前):
- 层的根元素
- 被定位了得元素并且
z-index值为负,相同z-index的情况下,按照HTML元素的书写顺序排列,下面相同。 - 没有被定位的元素
- 被定位的元素,并且
z-index值为auto - 被定位了的元素并且
z-index值为正。
注意:z-index值为负的元素比较特殊,他们会先被绘制,意味着他们可以出现在其他元素的后面,甚至出现在它的父元素后面。但是必要条件是该元素必须与父元素处于同一层,并且父元素不是这个层的根元素。一个很好的例子
理解了如何和什么时候会产生一个新的层,那么下次如果你遇到z-index值设了很大,但是不起作用的话就去看看它的祖先是否产生了一个新的层。
总结
说了这么多,我们来给之前的代码加上堆叠顺序。
<div><!-- 1 -->
<span class="red"><!-- 6 --></span>
</div>
<div><!-- 2 -->
<span class="green"><!-- 4 --><span>
</div>
<div><!-- 3 -->
<span class="blue"><!-- 5 --></span>
</div>
当我们设置了opacity之后变成下面这样。
<div><!-- 1 -->
<span class="red"><!-- 1.1 --></span>
</div>
<div><!-- 2 -->
<span class="green"><!-- 4 --><span>
</div>
<div><!-- 3 -->
<span class="blue"><!-- 5 --></span>
</div>
红色的<span>从6变成1.1,我用'.'来标记它是新生成的层里面的第一个元素。
最后我们来总结一下为什么红色的<span>会去到下面: 一开始有两个层,一个由根节点产生,一个由设置了z-index:1并且position:absolute的红色<span>产生。当我们设置了opacity时,产生了第三个层,并且第三个层把红色<span>产生的层包裹了,意味着刚开始的z-index的作用域只在第三个层里面。而所有的<div>都没有定位或者z-index,所以他们的堆叠顺序按照HTML出现顺序排列,于是第三个层就去到下面。
原文地址:http://www.w3cplus.com/css/what-no-one-told-you-about-z-index.html
没人告诉你关于z-index的一些事的更多相关文章
- 没人看系列-----html随笔
<!DOCTYPE> 目录 没人看系列-----html/css详解 前言 不多说这段时间写了好多好多前端的东西,以至于自己重新返回看了一遍前端的所有技术.故此做个总结,准备学东西的请绕行 ...
- 没人看系列----css 随笔
目录 没人看系列----css 随笔 没人看系列----html随笔 前言 没什么要说的就是自己总结,学习用的如果想学点什么东西,请绕行. CSS (Cascading Style Sheets)层叠 ...
- 一年三篇IF大于7的牛人告诉你怎么写SCI
一年三篇IF大于7的牛人告诉你怎么写SCI 1 研究生必备四本 俗话说好记性不如烂笔头,所以一定要首先养成做笔记的好习惯!作为研究生下面这几个本子是必不可少的: 1.实验记录本(包括试验准备本),这当 ...
- 【Python3爬虫】为什么你的博客没人看呢?
我相信对于很多爱好和习惯写博客的人来说,如果自己的博客有很多人阅读和评论的话,自己会非常开心,但是你发现自己用心写的博客却没什么人看,多多少少会觉得有些伤心吧?我们今天就来看一下为什么你的博客没人看呢 ...
- c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询
天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. 不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...
- 为什么你的 App 没人用?请按这8条逐一对照
为什么你的 App 没人用?请按这8条逐一对照 Kamo Asatryan 可能是这个世界上关注创新生态系统最多的一些人之一,他观察过数百个移动端 App,深入思考过它们的运行机制,并为它们的快速增长 ...
- 零基础想学习C语言,没资源、没人带、不知道从何开始?
初学编程的小伙伴经常会遇到的问题,1.没资源 2.没人带 3.不知道从何开始 ? 小编也是从新手期过来的,所以很能理解萌新的难处,现在整理一些以前自己学习买来的一些资料送给大家,希望对广大初学小伙伴有 ...
- [读书笔记]《没人会告诉你的PPT真相》
这本书分了三部分.第一部分偏重于基础技能,其中分为三部分,打印.放映.保存.第二部分是进阶,分为模板下载.模板修改.增加自定义页面等.第三部分是打造商业范的PPT,分为商业范的特征,具体技能体现(重复 ...
- docker~为什么没人说说.dockerignore
回到目录 最近一直专注于docker的开发之中,而在使用Dockerfile时发现有个问题,当你的发布目录只能是obj\Docker\publish,而指向其它目录dockefile并不认它,只有如何 ...
随机推荐
- WPF框架MVVM简单例子
MVVM是Model-View-ViewModel的缩写形式,它通常被用于WPF或Silverlight开发.Model——可以理解为带有字段,属性的类.View——可以理解为我们所看到的UI.Vie ...
- Asp.net窄屏页面 手机端新闻列表
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SearchNotice.a ...
- PHP定时器实现每隔几秒运行一次
php是服务器端脚本了并不像js那样有专业的settimeout函数来定时执行了,但只要浏览器不关闭各阶层是可以做到了,下面一起来看看. 下面写个简单例子来讲解这个方法. <?php ignor ...
- 【转载】 python修饰符@
@符号在python语言中具有特殊含义,用来作为修饰符使用, @修饰符有点像函数指针,python解释器发现执行的时候如果碰到@修饰的函数,首先就解析它,找到它对应的函数进行调用,并且会把@修饰下面一 ...
- 【翻译四】java-并发之线程暂停
Pausing Execution with Sleep Thread.sleep causes the current thread to suspend execution for a speci ...
- 基于类和基于函数的python多线程样例
不断的练,加深记忆吧. #!/usr/bin/env python # -*- coding: utf-8 -*- import threading import time exitFlag = 0 ...
- TortoiseSVN常用操作说明
TortoiseSVN是windows下其中一个非常优秀的SVN客户端工具.通过使用它,我们可以可视化的管理我们的版本库.不过由于它只是一个客户端,所以它不能对版本库进行权限管理. TortoiseS ...
- thinkphp自动验证中的静态验证和动态验证和批量验证
1.静态定义 在模型类里面预先定义好该模型的自动验证规则,我们称为静态定义. 举例说明,我们在模型类里面定义了$_validate属性如下: class UserModel extends Model ...
- git warning: LF will be replaced by CRLF in...
如果你有git项目,在提交代码的过程中可能会碰到上面的警告,特别是的项目中包含序列化对象的时候,你可能要小心!! 警告的含义是说换行符的,不同的操作系统的换行符是不一致的,如果你不清楚,真得看看这个 ...
- SpringJDBC解析4-query方法
重要步骤说明: 首先是从PersonServiceImpl方法进去,调用JdbcTemplate的query方法,然后执行一连串错中复杂的调用,而且里面有很多函数都是以回调形式处理, 1)JdbcTe ...