是,元素被遮挡后点击失效通常不是z-index值不够,而是未处于同一层叠上下文;应使用isolation: isolate作用于目标元素的直接父容器来创建独立层叠上下文。
不是。z-index 只在同一个层叠上下文(stacking context)内生效;如果父容器没创建层叠上下文,子元素的 z-index 再大也盖不过隔壁兄弟元素的渲染层。常见于轮播图按钮被图片遮住、弹窗内表单控件点不动、固定定位菜单被 iframe 或视频盖住——这些往往不是 z-index 值不够,而是根本不在同一层叠上下文中。
解决思路是主动创建新的层叠上下文,让目标元素及其子树“升维”,脱离原有渲染层级干扰。isolation: isolate 就是为此设计的轻量级方案:它不改变布局流,不触发重排,只单纯告诉浏览器:“请为这个容器建立独立的层叠上下文”。
isolation: isolate 必须作用在**目标交互元素的直接父容器**上(不是自己加在按钮上,而是加在按钮外层 div 上)position: relative + z-index: 0 效果类似,但语义更清晰、副作用更少(后者可能意外影响定位行为)isolation 在 IE 完全不支持,Edge 17+、Chrome 50+、Firefox 36+ 支持;若需兼容旧版 Edge 或 IE,得回退到 transform: translateZ(0) 或 will-change: transform
能用,但不推荐。这类 hack 的本质是触发“合成层(compositing layer)”,属于副作用驱动,容易引发意料外的性能问题:
opacity: 0.99 会强制开启 GPU 合成,但同时让元素半透明——即使视觉看不出,也可能导致文字抗锯齿异常或与 backdrop-filter 冲突transform: scale(1) 虽无视觉变化,但在某些安卓 WebView 中可能触发不必要的重绘;且若父容器有 overflow: hidden,缩放还可能造成裁剪错位isolation: isolate 是 CSS 标准中明确定义的层叠上下文触发方式,无视觉副作用,浏览器优化明确,调试工具里也能清晰看到“Stacking Context”标记完全不是一回事。contain: layout paint 是做渲染隔离,目的是提升性能:告诉浏览器“这个容器内的布局和绘制不会影响外部,外部变化也不必重绘它”。但它**不创建层叠上下文**,所以无法解决遮挡交互问题。
立即学习“前端免费学习笔记(深入)”;
举个典型反例:contain: layout paint 加在弹窗容器上,弹窗内按钮依然会被同级的 iframe 盖住——因为层叠顺序没变,只是绘制范围被限制了。
isolation: isolate(或 z-index 配合已有的层叠上下文)contain: layout paint
isolation 解决“能不能点”,contain 解决“点起来卡不卡”加了 isolation: isolate 还是点不了?大概率卡在这几个地方:
pointer-events: none(比如为了穿透点击下层地图),记得给交互子元素单独设回 pointer-events: auto
iframe 或 video 元素——它们默认处于顶层合成层,即使你创建了新层叠上下文,也要确保其 z-index 显式高于 iframe 的容器(iframe 自身不响应 z-index)isolation 只作用于 light DOM 范围;若交互元素在 shadow root 内,需在 shadow host 上设置Modal)内部已用 z-index 创建了多层上下文,此时盲目加 isolation 可能导致层级错乱,建议先 inspect 层叠上下文树(Chrome DevTools → Rendering → “Layer borders” + “Paint flashing”)层叠上下文不是开关,是树状结构;isolation: isolate 是其中最干净的“挂载点”之一,但挂哪、挂几层、挂完是否真在预期位置——得看树,不能只看代码。