opacity小于1会强制创建层叠上下文,使子元素z-index仅在内部生效,无法与兄弟元素跨上下文比层级;应改用rgba()/hsla()实现局部透明以避免此问题。
只要 opacity 值不等于 1(比如 0.99、0.5、0),浏览器就会为该元素创建一个新的层叠上下文(stacking context)。这不是可选行为,而是 CSS 规范强制要求的渲染机制。
一旦创建,这个新上下文就“隔绝”了内部和外部的 z-index 排序:子元素的 z-index 只在该上下文内部起作用,无法越过边界去和父级同级的其他元素比高低。
z-index: 9999,它也只在父元素的层叠上下文中排第一,不代表能盖住兄弟元素z-index 控制的层级关系会被打断position: relative; z-index: 10 的弹窗,如果加了 opacity: 0.99,就可能被后面 DOM 顺序更靠后的 position: fixed 导航栏挡住CSS 标准里没有“半透明才算触发”的阈值。规范明确写的是:opacity 不为 1 即触发。哪怕你写 opacity: 0.999999,浏览器也必须新建上下文——它不看视觉差异,只做数值判断。
这意味着:
opacity: 0.99 和 opacity: 0.1 在层叠行为上完全等价,都创建上下文opacity,哪怕只是“轻微淡化”opacity 做淡入淡出时,如果该元素同时参与复杂层叠(如模态框+下拉菜单+悬浮提示),务必提前检查是否被压住两者都能创建层叠上下文,但触发条件和副作用不同:
position: relative/absolute/fixed + z-index ≠ auto:只影响自身及后代的层叠顺序,不改变透明度opacity ≠ 1:既创建上下文,又让整个渲染盒子(含边框、背景、文字、所有子节点)统一降 alpha,且不可逆z-index: 100,只要它有 opacity: 0.9,它的子元素就无法靠 z-index: 999 跑到同级兄弟元素上面如果目标只是让背景或文字变半透,又不想牵连子元素或破坏层级,直接换颜色函数:
background-color: rgba(0, 0, 0, 0.5) 或 hsla(0, 0%, 0%, 0.5)
color: rgba(255, 255, 255, 0.7)
border-color: rgba(128, 128, 128, 0.3)
只有当你确实需要整个容器(含子内容)一起渐隐/渐显,才该用 opacity——但得接受它附带的层叠上下文代价。