关于层级树的概念,在MG12大大的 CSS z-index 属性的使用方法和层级树的概念
讲
的超级明白了,特别是“没有设置 z-index 时, IE8 以上和 W3C 浏览器的 z-index 默认值是 auto, 但 IE6 和
IE7 是
0”这点让我走出以前对于z-index认识的误区。IE系会有很多这种不同解析方式,比如对于type="email"之流IE向下兼容的方式强制解析
成text一样。浏览器们对于少年派都有着各自的理解,只是苦了开发者,突然想想以前教育为什么会有标准答案,就是为了开发者着想啊!
CSS
中的 z-index 属性
用
于设置节点的堆叠顺序, 拥有更高堆叠顺序的节点将显示在堆叠顺序较低的节点前面, 这是我们对 z-index 属性普遍的认识. 与此同时,
我们总是对堆叠顺序捉摸不透, 将 z-index 的值设得很大也未必能将节点显示在最前面. 本文将通过一些例子对 z-index
的使用方法进行分析, 并且为各位带入 z-index 层级树
的概念.
这个星期我们团队做了一次内部的技术分享, 南瓜小米粥
为我们分享了他对 CSS z-index 的理解和引入层级树这个概念
. 这个分享的现场效果很好, 所以我也将 z-index 和层级树话题搬到博客来谈一谈.
本文谈及多个影响节点显示层级的规则, 其中用到的所有例子全部罗列在《position 属性和 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 等特殊页面节点考虑, 如果有机会下次再为大家分享.
分享到:
相关推荐
本文将通过一些例子对 z-index 的使用方法进行分析, 并且为各位带入 z-index 层级树的概念. 目录 顺序规则 定位规则 参与规则 默认值规则 从父规则 层级树规则 参与规则 2 总结 顺序规则 如果不对节点设定...
综上所述,当遇到z-index为负值的元素无法点击的问题时,开发者可以采取调整z-index值、使用负margin属性或适当使用CSS重置样式等方法解决。在实施这些解决方法时,需要综合考虑页面布局和样式需求,以及浏览器兼容...
本文将深入探讨CSS中的z-index属性,解析其工作原理,以及如何在实际项目中正确使用它,同时也会提及一些在不同浏览器环境下的兼容性问题。 #### z-index的基本概念 z-index是CSS中用于控制元素堆叠顺序的属性。在...
### CSS中的Z-Index属性详解 #### 一、引言 在网页布局设计中,元素之间的堆叠顺序是非常重要的一个方面。特别是在复杂的页面结构中,如何控制这些元素的前后顺序,确保用户能够按照设计师的意图浏览信息,是前端...
在现代网页设计中,CSS属性z-index用于控制页面元素的堆叠顺序,即层叠上下文。一个元素的z-index值决定了它在页面上的“高度”,或者说是显示层级,拥有更高z-index值的元素会覆盖那些具有较低z-index值的元素。...
在处理网页布局时,经常会使用到CSS的z-index属性来控制不同元素之间的堆叠顺序。然而,不少人可能会遇到一个看似简单但实际上颇令人头疼的问题:明明已经设置了z-index属性,但是元素的层级却没有按照预期进行调整...
在CSS中,z-index是控制元素在垂直于屏幕方向上的堆叠顺序的属性。一个具有更高z-index值的元素将覆盖其下方z-index较低的元素。当元素在同一父容器内并且position属性不是static时,z-index才生效。 UEditor作为一...
构建项目的时候由于 采用的 antd of vue ui库 ,里面没有类似点击唤醒遮罩层的组件 ,所以自己手写vue组件进行引入 ,主要用的是 css3 z-index 属性 ,通过z-index 值不同进行层级展示。( ps :之前处理过类似需求 ...
在讨论CSS中的z-index属性时,我们通常用它来控制页面上元素的堆叠顺序。z-index属性值较大的元素将会覆盖z-index属性值较小的元素。在Web开发中,正确理解z-index的工作原理对于创建交互式和视觉上富有层次感的页面...
总之,正确使用`z-index`需要确保元素具有非静态的定位属性,并理解堆叠上下文和嵌套堆叠上下文的概念。通过调整`z-index`和`position`属性,可以有效地控制元素的叠加顺序,实现预期的视觉效果。在遇到`z-index`...
`z-index`是CSS中的一个属性,用于控制元素在堆叠上下文中的层级关系。具有较高`z-index`值的元素会覆盖具有较低`z-index`值的元素,前提是这些元素都在同一父容器内且拥有定位(position属性非static)。 在IE6中...
在网页设计和开发中,`z-index`是一个至关重要的CSS属性,它决定了元素在层叠上下文中的堆叠顺序。`z-index`的学习是前端开发者必须掌握的核心技能之一,尤其对于创建交互式、多层元素的网页至关重要。下面将详细...
总的来说,理解和掌握CSS中的堆叠上下文以及`z-index`的工作原理对于解决这类问题至关重要。在进行复杂的CSS布局设计时,应尽量减少对`transform`的依赖,或者在使用时充分考虑它对堆叠顺序的影响,从而避免类似的...
在CSS中,`z-index`属性是一个至关重要的概念,它用于控制元素的堆叠顺序,决定哪些元素在前面,哪些元素在后面。当多个元素在同一位置重叠时,`z-index`属性决定了它们的层级关系。`z-index`只对设置了定位属性(如...
解决IE6下z-index不工作的问题,不仅需要理解CSS属性的基本概念,还需要掌握特定浏览器的渲染规则。通过上述的几种方法,大多数情况下的z-index问题都可以得到解决。随着浏览器技术的不断进步,现代浏览器已经很少...
position值为非static时,如果不设置z-index属性,IE6/7下z-index默认为0,而IE8及以上浏览器z-index为auto,且zindex:auto的元素不参与堆叠优先级比较。 ff/chrome z-index IE6/7 IE8/9 不设置 0 auto au
1.问题的出现 写了一个平铺的列表,其中有些列表项具有hover出现的弹出框。希望达成的目标是弹出框展现时,要把列表项内容遮盖住,以保证弹出框内容优先展示。 元素的结构大致如下: 列表项1 ...