伪元素需直接设置 pointer-events: none 才能释放点击事件,因其默认拦截点击;父元素设置无效,因该属性不继承也不穿透;还需排查 overflow 裁剪、安卓 WebView 兼容性及层叠上下文干扰。
直接给伪元素加 pointer-events: none,不是父元素,也不是靠调 z-index。 伪元素(::before 或 ::after)只要渲染出来,默认就吃点击事件——哪怕只是画个 1px 边框、半透明遮罩或阴影,不加这个声明,底下按钮、输入框、链接全点不动。
浏览器事件捕获是自顶向下走的:pointer-events: none 只对当前元素生效,不“穿透”到子树,也不“跳过”祖先。如果遮挡的是 .card::after,你在 .card 上写 pointer-events: none,::after 依然会拦截点击,因为它的样式没被改。
很多“伪元素点不了”根本不是事件问题,而是它压根没渲染出来——被父容器硬切掉了。尤其在轮播、卡片、Modal 内部用伪元素画边框或阴影时高频出现。
iOS Safari 对该属性支持稳定,但安卓旧版 WebView(尤其是华为、小米系统浏览器)存在已知 bug:设了 none 却仍触发 click,或对 position: sticky 元素完全失效。
最常被忽略的一点:伪元素和父容器共用同一个层叠上下文,z-index: -1 看似能把它压到文字下面,但一旦父容器触发了新层叠上下文(比如加了 transform 或 opacity: 0.99),这个 z-index 就只在局部生效,反而让问题更难定位。所以比起调层级,优先用 pointer-events: none 切断事件流——干净、可控、不干扰布局。