前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库层叠上下文 创建条件 z-index
CSS盒模型与排版

哪些 CSS 属性会创建层叠上下文?为什么 z-index 写到 9999 还是盖不住?

层叠上下文可以理解成一个图层组,组里的 z-index 只在组内比较,整个组再作为一个整体和外面比。所以父元素一旦创建了层叠上下文,子元素的 z-index 写多大都跑不出父元素的层级。最常见的创建条件是定位元素设了 z-index、opacity 小于 1、transform 不为 none。

前端进阶之旅 · 一题精讲更新于 2026.09.29
CSS#盒模型与排版
先看核心答案读代码示例
理解线索

层叠上下文像嵌套的图层组

  1. 创建条件定位元素加 z-index、opacity、transform、filter、isolation: isolate 等
  2. 组内比较子元素的 z-index 只在所属上下文内排序,不和外面的元素直接比
  3. 整组参与外部排序整个上下文按创建它的元素自身的层级,和兄弟元素一起排

z-index 对 position: static 的普通元素无效,但对 Flex 和 Grid 的子项有效,不需要额外加 position。

核心回答

先记住这个答案

层叠上下文是一个独立的图层组。组内元素按 z-index 和层叠顺序排好,整个组再作为一个整体,用创建它的那个元素的层级去和外面比较。常见的创建条件有:根元素 html;position 为 relative 或 absolute 且 z-index 不是 auto;position: fixed 或 sticky;opacity 小于 1;transform、filter 不为 none;Flex 或 Grid 子项设了 z-index;isolation: isolate。它对 z-index 的影响是:子元素的 z-index 被限制在父级上下文里,父元素排在别人下面,子元素写 9999 也一样在下面。

  • z-index 只和同一个层叠上下文里的元素比
  • 父元素的层级决定了子元素能到的最高位置
  • 透明度与变换都可建层叠上下文
  • Flex 和 Grid 子项设 z-index 也会创建

弹窗写了 z-index: 9999 还被盖住

这是项目里最常见的场景。弹窗组件放在某个区块里,区块有淡入动画,用了 opacity。页面上的吸顶导航 z-index: 10,结果弹窗打开时被导航盖住了一截。

父元素的 opacity 把弹窗圈住了CSS
.header {
  position: sticky;
  top: 0;
  z-index: 10;
}

.section {
  opacity: 0.99; /* 动画残留,小于 1 就创建了层叠上下文 */
}

.section .modal {
  position: fixed;
  z-index: 9999; /* 只在 .section 内部有效 */
}

/* 结果:.section 整体按层级 0 和 .header 的 10 比较,
   .modal 虽然是 9999,也只能跟着 .section 排在 .header 下面 */

.modal 的 9999 只和 .section 里的其他元素比。到了外层,参与比较的是 .section 这个整体,它相当于 z-index: 0,比导航的 10 小,所以整个 .section 连同里面的弹窗都在导航下面。

怎么修
最稳的办法是把弹窗挂到 body 下面,React 用 createPortal,Vue 用 Teleport,这样弹窗就不受中间任何祖先的上下文影响。其次是去掉祖先上不必要的 opacity、transform,或者给 .section 本身设一个比导航大的 z-index,但后者会把整个区块都抬上去,往往不是想要的效果。

层叠上下文内部怎么排

在同一个上下文里,元素从下到上大致分成七层:上下文根元素的背景和边框,z-index 为负的子上下文,普通块级元素,浮动元素,行内元素,z-index 为 auto 或 0 的定位元素,z-index 为正的子上下文。同一层里后出现的盖住先出现的。

为什么负 z-index 的子元素还在父元素背景上面
子元素设了 z-index: -1,很多人以为它会跑到父元素后面去。如果父元素本身创建了层叠上下文,父元素的背景就是这个上下文的最底层,负 z-index 的子元素只能排在背景上面、普通内容下面。只有父元素不创建上下文时,子元素才可能钻到父元素背景后面,一直沉到更外层的上下文里。
opacity 和 transform 为什么也会创建
它们需要把元素和所有子元素当成一整块来处理。opacity: 0.5 要先把整块画好,再整体变半透明;如果子元素能和外面的元素交错排序,这一步就没法做。所以浏览器规定这些属性必须形成独立的上下文。filter、mask、mix-blend-mode 也是同样的原因。
回答前,多想一步

容易答错的地方

以为 z-index 越大就一定在上面
z-index 只在同一个层叠上下文里比较大小。两个元素分属不同上下文时,比的是它们各自往上找到的、处在同一上下文里的祖先。所以排查遮挡问题时先看祖先,不要先去改数字。
以为只有定位元素才会创建层叠上下文
opacity、transform、filter、will-change、contain: paint 这些和定位无关的属性都会创建。尤其是动画库给元素加的 transform 和 opacity,经常在不知不觉中制造出层叠上下文。
以为 position: relative 就会创建层叠上下文
单独的 position: relative 或 absolute 不会,必须同时设置了不为 auto 的 z-index。fixed 和 sticky 例外,在现代浏览器里它们自己就会创建。
试着用自己的话回答

面试官还会怎么问?

Flex 子项不设 position,z-index 会生效吗?

会生效。Flex 和 Grid 容器的子项只要设了不为 auto 的 z-index,就会参与层叠排序并创建层叠上下文,不需要额外写 position: relative。普通块级元素则必须先定位,z-index 才有效。

z-index: 0 和 z-index: auto 有什么区别?

对定位元素来说,两者在外部排序时位置差不多,都在「定位元素」那一层按文档顺序排。区别是 z-index: 0 会创建层叠上下文,子元素被圈在里面;auto 不会,子元素的 z-index 会直接参与外层的比较。

怎么避免项目里 z-index 越写越大?

先给全局层级定一套变量,比如下拉、吸顶、遮罩、弹窗、提示各占一档。弹层统一通过 Portal 挂到 body 下。组件根元素加 isolation: isolate,让内部层级只在组件内比较,这样组件里用 1、2、3 就够了。

从一道题,走向一组知识

把知识连起来

盒模型与排版

margin-top 写 50%,为什么算出来的是父元素宽度的一半?

两题关联不大,都属于「先找到参照对象再下结论」的 CSS 题,一个找层叠上下文,一个找包含块。

盒模型与排版

页面主体想在大屏上限宽居中、小屏上铺满,容器该怎么写?

两题关联不大,max-width 讲的是容器宽度,不涉及层级;放在一起复习的是盒模型基础。

参考资料

  • CSS:盒模型与排版参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 弹窗写了 z-index: 9999 还被盖住
  3. 层叠上下文内部怎么排
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑