普通的 html 层级覆盖顺序
- 普通流式布局,先渲染自己的背景与边框
- 再渲染 position 为 static 的 normal 子节点
- 再渲染 absolute 与 relative 子节点
- 显然,渲染顺序靠后的覆盖靠前的,层级结构完全可以按 dom 树来
- 那 fixed 等怎么办?
加个 stacking context 概念
- 不行了,渲染顺序不能纯依赖 dom 树结构
- 需要额外构建树表示渲染顺序,即 stacking contexts 树
- stacking context 以 stack level 来表示z-axis 顺序
- 子 stacking context 受制于祖先, stack level 是以父节点为原点
- 不是每个 dom 节点都有对应的 stacking context
哪些 dom 节点拥有 stacking context
- 根节点拥有根 stacking context
- fixed 元素 拥有
- 可定位元素(absolute, relative) 如果 z-index 有值(非auto),则拥有
- 其它CSS3新增添的需要额外渲染的元素,比如透明元素,旋转,透视等
- stacking context 的祖先关系按 dom 节点祖先关系
stacking context 的渲染顺序
- 渲染所关联元素的背景与边框
- 渲染负值的子 stacking context
- the in-flow, non-inline-level, non-positioned descendants.
- the non-positioned floats
- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
- 渲染stack level 为0 的子 stacking context(符合拥有规则而z-index为默认auto的) 或 可定位子元素.
- 渲染正值的子 stacking context
所以z-index 的作用在于
- 对 static 元素不起作用
- z-index 默认值为 auto, 如果值为 auto , 则stack level 为0
- 元素是否覆盖不能简单得看 z-index 值,而要看 stacking context 树
- 查看 stacking context 树可简单回溯 dom 树,把z-index有值的抽出来来查看
- 不知现代浏览器可有方便的工具查看?
对 z-index 的使用建议
- 只理解 z-index 字面意义的,最好不要用,不然都是坑(惨痛教训)
- 能靠dom节点流先后顺序解决的,就不要用 z-index
- 有 css3 transform 等特效的节点的子节点尽量避免使用 z-index, 不然树太复杂
- 加句吐槽:任何有点历史的东西,使用时都要警惕历史包袱,特别是不要看字面意
- "html与css最早只是为了富文本流的排版而设计的"