很多人对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. SimpleInjector与MVC4集成,与Web Api集成,以及通过属性注入演示

    SimpleInjector与MVC4集成,与Web Api集成,以及通过属性注入演示   1,与MVC集成 见http://simpleinjector.codeplex.com/wikipage? ...

  2. 杭电1162Eddy&#39;s picture

    Eddy's picture Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Tota ...

  3. 【Unity 3D】学习笔记三十八:角色控制器

    角色控制器 在unity中,已经帮我们实现的上下左右跳等动作,并将他们封装成了角色控制器.角色控制器保存在unity标准资源包中,能够说是很的强大.能够模拟第一或者第三人称视角.不受刚体的限制,很适用 ...

  4. Java数据结构与算法(4) - ch04队列(Queue和PriorityQ)

    队列: 先进先出(FIFO). 优先级队列: 在优先级队列中,数据项按照关键字的值有序,关键字最小的数据项总在对头,数据项插入的时候会按照顺序插入到合适的位置以确保队列的顺序,从后往前将小于插入项的数 ...

  5. 通用Key-Value存储系统的存储管理策略解析

            Key-Value存储作为NoSQL存储的一种常见方式,提供了比SQL数据库更好的可扩展性和读写性能. 比方当前开源最热门的Memcached和Redis:淘宝的Tair.腾讯的Cme ...

  6. 拥抱大家庭,nodejs走thrift

    拥抱大家庭,nodejs走thrift.最贱的例子,nodejs与nodejs之间走thrift对传. 1,官网下载 http://mirrors.cnnic.cn/apache/thrift/0.9 ...

  7. php设计模式(一):简介及创建型模式

    我们分三篇文章来总结一下设计模式在PHP中的应用,这是第一篇创建型模式. 一.设计模式简介 首先我们来认识一下什么是设计模式: 设计模式是一套被反复使用.容易被他人理解的.可靠的代码设计经验的总结. ...

  8. UITableView Cell 弹簧动画效果

    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath ...

  9. loadrunner必用函数web_reg_save_param获取多个符合边界值条件的使用方法

    在做loadrunner性能脚本开发时,常常碰见一个需求:符合web_reg_save_param函数中定义的左右边界值的值有多个,而我们的常规写法默认返回的是符合条件的第一个,而有时我们却需要使用后 ...

  10. Installshield在安装结束时刷新系统

    原文:Installshield在安装结束时刷新系统 在OnEnd里添加代码,两种解决方案 群友kevin的解决方案 #include "ifx.h"  //Call to Win ...