CSS 定位之 z-index 问题分析

去年我写过一篇《CSS z-index 属性的使用方法和层级树的概念》, 是对同事南瓜小米粥的分享内容的记录和总结, 引入了层技树的概念和分析其层级遮盖关系.

那篇文章很详细, 也很长; 南瓜小米粥也写了一篇《CSS 定位之 z-index 问题分析》, 清晰简单, 现转发如下.

CSS z-index 属性

关于 z-index, 目前遇到的一些问题

  1. 某些浏览器下元素层级遮盖存在 bug.
  2. 某个元素 z-index 设的太大, 导致始终无法被遮盖.
  3. JavaScript 动态计算 z-index, 导致元素覆盖关系部可控.

层级遮盖 bug 出现的原因

  1. IE6/7 对 z-index 的表现跟 IE8 及以上浏览器不一致.
  2. position 值为非 static 时, 如果不设置 z-index 属性, IE6/7 下 z-index 默认为 0, 而 IE8 及以上浏览器 z-index 为 auto, 且 zindex:auto 的元素不参与堆叠优先级比较.
    z-index IE6/7 IE8/9 Firefox/Chrome
    不设置 0 auto auto
    number number number number

层级关系的比较

先看几点结论:

  1. 对于同级元素, 默认 (或 position:static) 情况下文档流后面的元素会覆盖前面的.
  2. 对于同级元素, position 不为 static 且 z-index 存在的情况下 z-index 大的元素会覆盖 z-index 小的元素, 即 z-index 越大优先级越高.
  3. IE6/7 下 position 不为 static, 且 z-index 不存在时 z-index 为 0, 除此之外的浏览器 z-index 为 auto.
  4. z-index 为 auto 的元素不参与层级关系的比较, 由向上遍历至此且 z-index 不为 auto 的元素来参与比较.

在上面 2 点结论的基础上, 我们引入定位树(非 W3C 官方词汇) 的概念来做层级的比较. 在定位树这个概念下, 浏览器在渲染 DOM 节点时, 除了生成 DOM 树之外, 还会根据 DOM 树中的定位元素 (position 不为 static) 生成定位树.

DOM 树 (左上), 定位树 (右下) 对比如下图 (其中边上有红色圆圈的表示该元素 position 不为 static).

DOM 树和定位树

可以这样理解:定位树中包含了 DOM 树中 position 不为 staitc 的全部元素. 而非同级元素比较层级关系可以比较如下.

  • 向上遍历定位树的父节点直到 2 个元素为同级元素.
  • 根据上面的结论来最最后的比较, 层级高的元素会越靠近用户的显示器并能覆盖层级低的元素

实例

假设上图中所有标红色元素 position 都不为 static; 且 z-index=1, 根据上面的比较规则可以知道:

  • c > (b && b *) > (a && a *) 即元素 c 及 c 的所有定位元素层级比 a 和 b 高.
  • m > h, g > k 和 d > m.

假设 a 的 position 不为 static, z-index 属性不存在, 定位树中 a 的子元素 z-index 一次分别为 1,2,3,4... 其它定位元素 z-index:1, 根据结论三有:

  • IE6/7 下 b > (a && a *) 即元素b的层级比 a 及 a 的所有定位元素层级高.
  • 其它浏览器下 i > h > b > d.

后话

南瓜小米粥在 CSS 方面研究比较深入, 除了 z-index, 还有很多相关内容和工具分享可以到他博客去看看. 关于这个 z-index 层级关系问题, 转过来的这个文章比较概要并配有实例的文章, 能够满足大部分人需求; 而我之前写的文章整理了一套规则, 需要深入研究的朋友务必去看看.


你可能感兴趣的:(CSS 定位之 z-index 问题分析)