很多人对z-index的认识仅止于:z-index是控制元素在页面中的堆叠顺序,z-index值高的元素显示在z-index值低的前面。而其中的原因才很少有人去深究,直到自己在实际项目中碰到由于z-index而导致的各种bug时,才会搜索一下解决的办法。但z-index其实是包含着属于自己一套浏览器解析规则的,只要了解了这其中的规则,那么控制页面中的元素便随心所欲了。

z-index的使用条件

只对有 position 属性的且值不为static的元素才有效

堆栈上下文

一组具有共同双亲的元素,按照堆栈顺序一起向前或向后移动构成了所谓的堆栈上下文。充分理解堆栈上下文是真正掌握z-index和堆栈顺序工作原理的关键。

堆栈上下文有三种方法可以在一个元素上形成:(针对标准的浏览器,IE系列有点小区别)

  1. 当一个元素是文档的根元素时(<html>元素)
  2. 当一个元素有一个position值而不是static,有一个z-index值而不是auto
  3. 当一个元素有一个opacity值小于1

前两种形成堆栈上下文的方法具有很大意义并且被广大Web开发者所理解(即使他们不知道这些被叫做什么)。第三种方法(opacity)几乎从来没在w3c说明文档之外被提及过。

示例

span{display: block;width: 50px;height: 50px;position: absolute;}
.red{background-color: red;}
.green{background-color: green;margin: 15px;}
.blue{background-color: blue;margin: 30px;} <div><span class="red"></span></div>
<div><span class="green"></span></div>
<div><span class="blue"></span></div>

显示为:

当修改css

 red{background-color: red;z-index:;position: relative;}

再添加一条css规则

div:first-child{opacity: 0.99;}

再添加

div:first-child{opacity: 0.99;z-index:;position: relative;}

从上面可以看出,一个元素的堆叠顺序,不仅仅取决于它自身的z-index,更要看它所处在的堆栈上下文,如果所处的上下文的层级很低,即使他本身的z-index设置的很高,也无法实现你的要求。

上面的例子中使用的是opaciry<1的方式来生成一个堆栈上下文的,红色的方块在其父级没有创建堆栈上下文的时候,给他添加一个高的z-index,可以实现覆盖绿色和蓝色的方块,当给红色方块的父级div添加了opacity<1的时,产生了一个堆栈上下文,此时它的z-index设置的再高也无法覆盖绿蓝了,它的z-index只能相对于同样在这个堆栈上下文中的元素起作用,而无法影响到不在这个上下文中的元素。

而如果想要再次覆盖绿蓝方块的话,只能将这整个堆栈上下文的z-index值提高,也就是给红色方块的父级div加一个z-index。用一句话说,就是拼爹的时候到了!如果你在项目中发现你给一个元素设置再高的z-index也不起作用的时候,就要检查一下他的父级,祖先了,是否产生了一个堆栈上下文,将后代元素限制了。如果是的话,要么修改这个元素的属性使其不再产生堆栈上下文,要么就给这个上下文设置一个较高的符合自要求的z-index值。

上面讨论的z-index解析规则都是基于标准的符合w3c规范的浏览器,如果浏览器都遵循规范的话,前端的世界就清爽多了,但IE系列的浏览器总是让你要多费一番功夫。

IE中z-index跟标准浏览器中的解析有一个小小的区别,那就是上面说的产生堆栈上下文中的三个条件中,对第二个条件的支持的区别,在标准浏览器中元素必须是有z-index值的同时要有position属性,且值不为static,满足这两个条件,才会产生一个新的堆栈上下文,但低版本的IE中就不管这么多了,只要你设置了position值不为static,他就会生成一个新的堆栈上下文。

这里就直接引用代码了:

<style> 
  .parent{width:200px; height:200px; padding:10px;}
  .sub{text-align:right; font:15px Verdana;width:100px; height:100px;}
  .lt50{left:50px;top:50px;}
</style>
<div style="position:absolute; background:lightgrey;" class="parent">
  <div style="position:absolute;z-index:20;background:darkgray;" class="sub">20</div>
  <div style="position:absolute;z-index:10;background:dimgray;" class="sub lt50">10</div>
</div>
<div style="position:absolute;left:80px;top:80px;background:black;" class="parent">
  <div style="position:absolute;z-index:2;background:darkgray;" class="sub">2</div>
  <div style="position:absolute;z-index:1;background:dimgray;" class="sub lt50">1</div>
</div>

很明显,灰色容器和黑色容器是同级的,遵循后来居上的原则,黑色容器是在灰色容器之上的,在低版本IE中因为两容器都设置了postion属性,新生成了堆栈上下文,因此,即便1,2 的z-index 小于 20,10,但由于所处的堆栈上下文整体环境要高,因此,1、2以及黑色容器的层级要高于灰色的容器及其内部的所有元素。而标准模式中容器没有生成堆栈上下文,因此,20,10,2,1以及两个容器的层级都是按照之前说的解析规则来算的。

解决的办法

就像在解决触发了ie中hasLayout而没有触发标准中的BFC那样,只要在可能出现定位元素相互覆盖的情况时,明确指定定位元素的 z-index的值,就可以避免此类的情况。

参考资料

z-index 解析的更多相关文章

  1. 用c#自己实现一个简单的JSON解析器

    一.JSON格式介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着很多优点.例如易读性更好,占用空间更 ...

  2. Spring 系列教程之默认标签的解析

    Spring 系列教程之默认标签的解析 之前提到过 Spring 中的标签包括默认标签和自定义标签两种,而两种标签的用法以及解析方式存在着很大的不同,本章节重点带领读者详细分析默认标签的解析过程. 默 ...

  3. Django url反向解析与路由分发名称空间

    url反向解析 url.py from django.conf.urls import url from django.contrib import admin from app01 import v ...

  4. Spring源码分析(七)bean标签的解析及注册

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在上一篇中提到过Spring中的标签包括默认标签和自定义标签两种,而两种 ...

  5. Python多继承解析顺序的C3线性算法流程解析

    Python多继承MRO 在Python2.1中,采用了经典类,使用深度优先算法解析. Python2.2中,引入了新式类,使用深度优先算法和广度优先算法. 在Python2.3以后的版本中,经典类和 ...

  6. spring源码深度解析— IOC 之 默认标签解析(上)

    概述 接前两篇文章  spring源码深度解析—Spring的整体架构和环境搭建  和  spring源码深度解析— IOC 之 容器的基本实现 本文主要研究Spring标签的解析,Spring的标签 ...

  7. flask 反向解析示例

    1 静态网页 和动态网页 1 静态网页:无法与服务器做动态交互的网页 2 动态网页:允许与服务器做动态加护的 2 WEB 与 服务器 1 WEB :网页(HTML,css,JS) 3 服务器的作用: ...

  8. 深入浅出 Vue.js 第九章 解析器---学习笔记

    本文结合 Vue 源码进行学习 学习时,根据 github 上 Vue 项目的 package.json 文件,可知版本为 2.6.10 解析器 一.解析器的作用 解析器的作用就是将模版解析成 AST ...

  9. spring源码学习之默认标签的解析(一)

    继续spring源码的学习之路,现在越来越觉得这个真的很枯燥的,而且我觉得要是自己来看源码,真的看不下去,不是没有耐心,而是真的没有头绪,我觉得结合着书来看,还是很有必要的,最起码大致的流程是能够捋清 ...

  10. Spring IoC 默认标签解析

    前言 本系列全部基于 Spring 5.2.2.BUILD-SNAPSHOT 版本.因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析. 本篇文章主要介绍 Spring IoC 容 ...

随机推荐

  1. 【百度地图API】圣诞节里不会迷路的麋鹿——驾车导航

    原文:[百度地图API]圣诞节里不会迷路的麋鹿--驾车导航 任务描述: 可能大家还不知道,圣诞老人是爱迷路的老爷爷! 今年圣诞节又要到了,圣诞老人又要出来送礼物了.可是,他灰常的迷路呢! 还好,他有一 ...

  2. [CLR via C#]1.1 将源代码编译成托管代码

    原文:[CLR via C#]1.1 将源代码编译成托管代码 1. 公共语言运行时(Common Language Runtime,CLR)是一种可由多种编程语言使用的"运行时". ...

  3. 我在Github上的flare-spark项目

    Flare-Spark 介绍 我在自己的github上建了个flare-spark项目,本身是Apache Spark项目Master分支的镜像.在Spark的基础上,添加了flare子项目. 估计大 ...

  4. Font-Awesome 体验 鼠标进入图标变大

    <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> &l ...

  5. ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上

    原文:ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上 ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model ...

  6. 一张地图,告诉你NodeJS命令行调试器语句

    NodeJS提供脚本调试. 进入node debug xx.js您可以进入调试模式. 版权声明:本文博客原创文章,博客,未经同意,不得转载.

  7. 如果在VMware上免费下载驱动

    1.在不登录,或者没有账号的情况下,进入VMare的驱动下载界面,可以发现有一个大大的Download按钮. 2.点这个按钮,会提示登录. 3.注册账号登录后,回到驱动下载界面,会发现Download ...

  8. 用erlang写的kmp算法

    Knuth-Morris-Pratt 字符串查找算法,简称为 "KMP算法",常用于在一个文本串S内查找一个模式串P 的出现位置,这个算法由Donald Knuth.Vaughan ...

  9. 从PHP官网被攻击,到熟悉SSL(安全链路层)

    近日,php官网php.net网站受到恶意攻击,攻击者至少破坏了2个服务器.PHP工作组不得不重置用户密码. PHP工作组在随后的调查发现,攻击者成功的对网站注入了恶意的JavaScript代码,这个 ...

  10. 查询职责分离(CQRS)模式

    查询职责分离(CQRS)模式 在常用的三层架构中,通常都是通过数据访问层来修改或者查询数据,一般修改和查询使用的是相同的实体.在一些业务逻辑简单的系统中可能没有什么问题,但是随着系统逻辑变得复杂,用户 ...