普通的 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最早只是为了富文本流的排版而设计的"
go to ppt index