z-index的值受position影响,而且还受父级元素影响。有很多种情况。下面是我看的一个特别全的网址,讲的很详细,收藏了,以后温故用。

对应的例子页面:http://www.neoease.com/tutorials/z-index/

顺序规则

如果不对节点设定 position 属性, 位于文档流后面的节点会遮盖前面的节点.

<div id="a">A</div>
<div id="b">B</div>

  

定位规则

如果将 position 设为 static, 位于文档流后面的节点依然会遮盖前面的节点浮动, 所以 position:static 不会影响节点的遮盖关系.

<div id="a" style="position:static;">A</div>
<div id="b">B</div>

  

如果将 position 设为 relative (相对定位), absolute (绝对定位) 或者 fixed (固定定位), 这样的节点会覆盖没有设置 position 属性或者属性值为 static 的节点, 说明前者比后者的默认层级高.

<div id="a" style="position:relative;">A</div>
<div id="b">B</div>

  

在没有 z-index 属性干扰的情况下, 根据这顺序规则和定位规则, 我们可以做出更加复杂的结构. 这里我们对 A 和 B 都不设定 position, 但对 A 的子节点 A-1 设定 position:relative. 根据顺序规则, B 会覆盖 A, 又根据定位规则 A' 会覆盖 B.

<div id="a">
<div id="a-1" style="position:relative;">A-1</div>
</div>
<div id="b">B</div>

  

上面互相覆盖在什么时候用到这样的实现? 看起来偏门, 其实很常用, 比如说, 电子商务网站侧栏的类目展示列表就可以用这个技巧来实现.

下图是某网站的类目展示区域, 二级类目的悬浮层覆盖一级类目列表外框, 而一级类目的节点覆盖二级类目的悬浮层. 如果使用 CSS 实现展示效果, 一级类目的外框相当于上面例子中的 A, 一级类目的节点相当于 A-1, 二级类目的悬浮层相当于 B.

参与规则

我们尝试不用 position 属性, 但为节点加上 z-index 属性. 发现 z-index 对节点没起作用.

<div id="a" style="z-index:2;">A</div>
<div id="b" style="z-index:1;">B</div>
<div id="c" style="z-index:0;">C</div>

  

W3C 对 z-index 属性的描述中提到 在 z-index 属性仅在节点的 position 属性为 relative, absolute 或者 fixed 时生效.

The z-index property specifies the stack order of an element. Only works on positioned elements(position: absolute;, position: relative; or position: fixed;).

<div id="a" style="z-index:2;">A</div>
<div id="b" style="position:relative;z-index:1;">B</div>
<div id="c" style="position:relative;z-index:0;">C</div>

  

默认值规则

如果所有节点都定义了 position:relative. z-index 为 0 的节点与没有定义 z-index 在同一层级内没有高低之分; 但 z-index 大于等于 1 的节点会遮盖没有定义 z-index 的节点; z-index 的值为负数的节点将被没有定义 z-index 的节点覆盖.

<div id="a" style="position:relative;z-index:1;">A</div>
<div id="b" style="position:relative;z-index:0;">B</div>
<div id="c" style="position:relative;">C</div>
<div id="d" style="position:relative;z-index:0;">D</div>

  

通过检查我们还发现, 当 position 设为 relative, absolute 或者 fixed, 而没有设置 z-index 时, IE8 以上和 W3C 浏览器 (下文我们统称为 W3C 浏览器) 的 z-index 默认值是 auto, 但 IE6 和 IE7 是 0.

从父规则

如果 A, B 节点都定义了 position:relative, A 节点的 z-index 比 B 节点大, 那么 A 的子节点必定覆盖在 B 的子节点前面.

<div id="a" style="position:relative;z-index:1;">
<div id="a-1">A-1</div>
</div> <div id="b" style="position:relative;z-index:0;">
<div id="b-1">B-1</div>
</div>

  

如果所有节点都定义了 position:relative, A 节点的 z-index 和 B 节点一样大, 但因为顺序规则, B 节点覆盖在 A 节点前面. 就算 A 的子节点 z-index 值比 B 的子节点大, B 的子节点还是会覆盖在 A 的子节点前面.

<div id="a" style="position:relative;z-index:0;">
<div id="a-1" style="position:relative;z-index:2;">A-1</div>
</div> <div id="b" style="position:relative;z-index:0;">
<div id="b-1" style="position:relative;z-index:1;">B-1</div>
</div>

  

很多人将 z-index 设得很大, 9999 什么的都出来了, 如果不考虑父节点的影响, 设得再大也没用, 那是无法逾越的层级.

层级树规则

可能你会觉得在 DOM 结构中的兄弟节点会拎出来进行比较并确定层级, 其实不然.

<div id="a" style="position:relative;z-index:2;">
<div id="a-1" style="position:relative;z-index:0;">A-1</div>
</div> <div id="b">
<div id="b-1" style="position:relative;z-index:1;">B-1</div>
</div>

  

我们认为同时将 position 设为 relative, absolute 或者 fixed, 并且 z-index 经过整数赋值的节点, 会被放置到一个与 DOM 不一样的层级树里面, 并且在层级树中通过对比 z-index 决定显示的层级. 上面的例子如果用层级树来表示的话, 应该如下图所示.

图中虽然 A-1 (z-index:0) 的值比 B-1 (z-index:1) 小, 但因为在层级树里 A (z-index:2) 和 B-1 在一个层级, 而 A 的值比 B-1 大, 根据从父规则, A-1 显示在 B-1 前面.

参与规则 2

前面提到的参与规则认为只要节点的 position 属性为 relative, absolute 或者 fixed, 即可参与层级比较, 其实不准确. 如果所有节点都定义了 position:relative, 并且将 z-index 设为整数值, 根据从父规则, 父节点的层级决定了子节点所在层级.

<div id="a" style="position:relative;z-index:0;">
<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div> <div id="b">
<div id="b-1" style="position:relative;z-index:0;">
<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
</div>
</div> <div id="c" style="position:relative;z-index:0;">
<div id="c-1">
<div id="c-1-1">
<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
</div>
</div>
</div>

  

例子中 A, B-1, C-1-1 作为父节点, z-index 的值相同, 根据顺序规则, C-1-1 在 B-1 之前, B-1 在 A 之前; 又根据从父规则, 无论子节点的 z-index 值是什么, C-1-1-1 在 B-1-1 之前, B-1-1 在 A-1 之前.

如果我们将所有父节点的 z-index 属性去除, 诡异的事情发生了. IE6 和 IE7 浏览器显示效果不变, 而 W3C 浏览器的子节点不再从父, 而是根据自身的 z-index 确定层级.

<div id="a" style="position:relative;">
<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div> <div id="b">
<div id="b-1" style="position:relative;">
<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
</div>
</div> <div id="c" style="position:relative;">
<div id="c-1">
<div id="c-1-1">
<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
</div>
</div>
</div>

  

根据默认值规则, IE6 / IE7 和 W3C 浏览器上的元素存在 z-index 默认值的区别. 我们相信, 仅当 position 设为 relative, absolute 或者 fixed, 并且 z-index 赋整数值时, 节点被放置到层级树; 而 z-index 为默认值时, 只在 document 兄弟节点间比较层级. 在 W3C 浏览器中, A, B-1 和 C-1-1 的 z-index 均为 auto, 不参与层级比较.

而在 IE6 和 IE7 中, 因为 z-index 的默认值是 0, 所以也参与了层级比较.

设置了 position 而没有 z-index 的节点虽然不参与层级树的比较, 但还会在 DOM 中与兄弟节点进行层级比较.

 
<div id="a" style="position:relative;">
<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div> <div id="b">
<div id="b-1">
<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
</div>
</div> <div id="c" style="position:relative;">
<div id="c-1">
<div id="c-1-1">
<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
</div>
</div>
</div>

  

我们对上个例子改造一下, 将 B-1 的 position 属性删除后, W3C 浏览器显示如下图. 根据定位规则, A 和 C-1-1 会显示在 B-1 的前面; 而根据顺序规则, C-1-1 又显示在 A 前面.

在 IE6 和 IE7 中, 因为 A 和 C-1-1 设置了 position:relative, 而且 z-index 的默认值为 0, 所以也参与层级树比较, 所以有如下效果.

总结

浏览器节点显示层级是一个费力的活, 今天你觉得 A 区块会永远置顶, 但明天因为需求变动, 突然出现 B 元素需要置顶. 一层一层往上堆砌, 某天回头一看, 发现很多区块交错在一起, 而且他们的值一个比一个大, 根本搞不清头绪. 我觉得在操刀干活之前, 最好先将 position, z-index 和层级的关系搞搞清楚, 以免后患无穷.

另外, 非情非得已, 切勿用 JavaScript 计算 z-index, 并将某个节点的 z-index 设置成所有节点中层级最高.

因为篇幅太长, 本文仅从节点属性角度进行讨论, 没有涉及 select 和 iframe 等特殊页面节点考虑, 如果有机会下次再为大家分享.

css 的z-index研究的更多相关文章

  1. CSS技能汇总,研究及实践

    最近一直在研究CSS,因为发现实践中大部分时间都在写CSS,且自己感觉写的很烂,虽然以前看的很多,但却很少有去实践过,更别提研究了,现在发现根本就不是你懂你就会,很多都是你用着用着才真的会了的,于是现 ...

  2. 盒子端 CSS 动画性能提升研究

    不同于传统的 PC Web 或者是移动 WEB,在腾讯视频客厅盒子端,接大屏显示器(电视)下,许多能流畅运行于 PC 端.移动端的 Web 动画,受限于硬件水平,在盒子端的表现的往往不尽如人意. 基于 ...

  3. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  4. 纯CSS实现JS效果研究

    利用CSS3:checked选择器和~配合实现tab切换 效果: 代码: <style> body,div,input,label{ margin:0; padding:0; } #tab ...

  5. 尖刀出鞘的display常用属性及css盒模型深入研究

    一:diplay:inline-block 含义:指元素创建了一个行级的块级元素,该元素内部(内容)被格式化成一个块级元素,同时元素本身则被格式化成一个行内元素.更简单的说就是说inline-bloc ...

  6. img和css背景的选择

    在什么情况下更适合使用HTML IMG标签来显示一个图像,而不是一个CSS有背景图像,反之亦然? 如下场景使用img标签比较合适: 1.如果图像是等内容的一部分或图表或人(真正的人,而不是股票图人), ...

  7. 深入理解CSS中的层叠上下文和层叠顺序(转)

    by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=5115 零.世间的道 ...

  8. 深入理解CSS中的层叠上下文和层叠顺序

    零.世间的道理都是想通的 在这个世界上,凡事都有个先后顺序,凡物都有个论资排辈.比方说食堂排队打饭,对吧,讲求先到先得,总不可能一拥而上.再比如说话语权,老婆的话永远是对的,领导的话永远是对的. 在C ...

  9. Discuz! X的CSS加载机制

    首先,每个页面都会加载以下两个css,data/cache/style_1_common.css和data/cache/style_1_forum_index.css.先讲讲这两个文件名的命名规则:第 ...

  10. CSS水平居中和垂直居中解决方案

    一.CSS 居中 — 水平居中 DIV等标签本身没有定义自己居中的属性,网上很多的方法都是介绍用上级的text-align: center,然后嵌套一层DIV来解决问题. 可是这个方法有时候完全不起作 ...

随机推荐

  1. webpack构建具备版本管理能力的项目

    webpack是时下十分流行的编译和打包工具,它提供一种可扩展的loader的方式,简单的配置,便可以编译打包各类型的文件,包括js.css.image.font.html,以及各种预编译语言都不在话 ...

  2. 从客户端(Content="<p>666</p>")中检测到有潜在危险的 Request.Form 值。

    出现:从客户端(Content="<p>测试</p>")中检测到有潜在危险的 Request.Form 值. 一般是在线编辑器有HTML标签的,我是用的MV ...

  3. ExtJs4.0入门错误

    当在eclipse中的web工程中增加了extjs4,出现An internal error occurred during: "Building workspace". Java ...

  4. iOS 获取系统目录

    //获取根目录 NSString *homePath = NSHomeDirectory(); NSLog(@"Home目录:%@",homePath); //获取Document ...

  5. Spring学习之Ioc控制反转(1)

    开始之前: 1. 本博文为原创,转载请注明出处 2. 作者非计算机科班出身,如有错误,请多指正 ---------------------------------------------------- ...

  6. oracle使用还原段的目的和还原数据的管理方法及还原段的类型

    一.引入还原段主要有3个目的: 1.事务回滚:主要是针对rollback语句起作用 2.事务恢复:非正常关闭数据库即非保留事务级关闭数据库(abort.immediate)或者数据库instance崩 ...

  7. jq插件第二款来袭 图片滚动

    这第二款也是非常实用的插件,也是与图片相关,关于图片的需求太多了,这个是图片滚动哦,不过不是无缝滚动,是左像右滚动,到头的话再往回滚动,利用scrollLeft实现的,支持自动滚动和每次滚动的个数默认 ...

  8. Canvas基础学习(一)——实现简单时钟显示

    HTML5最受欢迎的功能就是<canvas>元素.这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态地在这个区域中绘制图形.关于<canvas>元素的一些 ...

  9. Redis存储Session

    net Core 使用Redis存储Session   前言 Asp.net Core 改变了之前的封闭,现在开源且开放,下面我们来用Redis存储Session来做一个简单的测试,或者叫做中间件(m ...

  10. C# 几种常见的排序方法

    1.冒泡排序 //冒泡排序 public void BubbleSort(int[] list) { int i, j, temp; bool done = false; j = ; while (( ...