很多人对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. hdu4324 Triangle LOVE (拓扑排序)

    这是一道最简单的拓扑排序题,好久没看这个算法了! 有点生疏了! 后附上百度的资料; #include<stdio.h> #include<string.h> int in[50 ...

  2. Python - 安全替换字符串模板(safe_substitute) 详细解释

    安全替换字符串模板(safe_substitute) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27057339 字 ...

  3. 从头开始学JavaScript (三)——数据类型

    原文:从头开始学JavaScript (三)--数据类型 一.分类 基本数据类型:undefined.null.string.Boolean.number 复杂数据类型:object object的属 ...

  4. javascript权威指南(2)

    JavaScript预定义了一系列全局变量和函数,在自定义变量和函数式要避免使用这些预定义的名称: arguments encodeURI  Infinity  Number  RegExp Arra ...

  5. 私人定制javascript中函数小知识点

    函数的定义 首先在javascript中,函数就是对象,程序可以随意操控它们.比如,可以给它们设置属性,甚至调用它们的方法.函数使用function关键字来定义.它既可以用在函数定义表达式,也可以用在 ...

  6. krpano音量控制(我们已经转移到krpano中国网站 krpano360.com)

    需求: 实现音量控制,这是官网的样例, 本文已经转移 到 krpano中文网 p=148">http://krpano360.com/? p=148 很多其它教程关注微信公众号 krp ...

  7. struts2的Action该方法不能去

    最近做的一个特征,使用struts2,input标签内容,并与相应的内容背景的实体类,当提交方法,无法进入action该方法和程序没有报错被,检验N通方法还没有找到,查找终于找到了,它是input标签 ...

  8. c# 自定义数据类型

    定义引用类型用 class  ,值类型 用 struct ,涉及数据转换就用 上一篇的方法做 ,涉及 泛型就用 in  关键字 不用 in interface IContravariant<A& ...

  9. 如何将sqlserver表中的数据导出sql语句或生成insert into语句 [转]

    输入表名,生成插入语句 drop proc proc_insert //如果存在就删除 go create proc proc_insert (@tablename varchar(256)) as ...

  10. 超高性能的json序列化

    超高性能的json序列化之MVC中使用Json.Net 超高性能的json序列化之MVC中使用Json.Net 先不废话,直接上代码 Asp.net MVC自带Json序列化 1 /// <su ...