z-index必须配合position使用,仅设z-index而未设position(即保持static)时完全无效;常见失效原因包括元素未定位、父级创建层叠上下文隔离子元素,或同层z-index相同导致后渲染者覆盖前者。

z-index 不是单独生效的属性,它必须和 position 配合使用——只写 z-index: 999 却没设 position,浏览器直接忽略。
为什么给元素加了 z-index 却没反应?
最常见原因是元素仍为 position: static(默认值)。CSS 规范明确规定:z-index 只对 position 值为 relative、absolute、fixed 或 sticky 的元素有效。
- 检查开发者工具中该元素的
Computed样式:如果position显示为static,z-index就一定不生效 - 哪怕写了
z-index: 9999,只要position没改,Computed中z-index仍显示为auto - 表格相关元素(
<table>、<code><tr>、<code><td>)尤其容易踩这个坑——它们默认都是 <code>static,且<tr> 和 <code><td> 在标准模式下强制忽略 <code>position声明position: relative是最安全的起点对大多数需要微调层叠顺序的块级元素(比如
<div>、<code><section></section>、甚至<table>),优先用 <code>position: relative——它不脱离文档流,不影响布局,只启用z-index能力。<table style="position: relative; z-index: 10"> 可让整张表作为一个整体浮起,盖住其他静态内容 <li>不要给 <code><tr> 直接加 <code>position:部分浏览器会渲染异常(如边框错位、高度塌陷)- 想让某个单元格内容“弹出”,正确做法是:在
<td> 内部套一层 <code><div class="popup-wrapper">,再给这个 <code><div> 设 <code>position: relative; z-index: 100为什么
z-index数值很大还是被盖住?真正卡住的不是数值大小,而是层叠上下文(stacking context)被意外隔离。父级一个
transform、opacity: 0.99或filter,就能把子元素锁死在局部上下文中。- 即使
<table> 设了 <code>z-index: 9999,只要它的父容器有opacity: 0.99,整张表就只能和父容器内部其他元素比高低,无法压过页面顶部导航栏 - Chrome DevTools → Layers 面板能直观看到元素是否被框进独立“层”里
- 临时验证方法:在父容器上加
outline: 1px solid red,然后逐个注释掉可疑的transform、will-change、filter等属性 - 对弹窗、下拉菜单这类浮层,更稳妥的做法是用 JS 把它们
appendChild到document.body底部——天然脱离原有上下文,靠 DOM 顺序 + 基础z-index分组就能稳住层级
真正难的不是写
z-index,而是看清当前元素处在哪个层叠上下文中、它的父级有没有悄悄把它关进“房间”。数值只是最后一环,上下文才是开关。 - 即使











