必须用 position: relative 的父容器,因为 ::before 伪元素默认相对于最近的已定位祖先定位,若父容器未设 position: relative,它会向上查找直至 ,导致遮罩错位。

直接用 ::before 伪元素加 position: absolute 就能给图片加半透明遮罩,但必须配 position: relative 的父容器,否则遮罩会定位错乱。
为什么必须用相对定位的父容器?
伪元素默认相对于最近的已定位祖先(position 不是 static)定位。如果父容器没设 position: relative,::before 会往上找,最终可能相对于 定位——遮罩就飘到页面角落去了。
- 父容器必须写
position: relative,哪怕它只是个空<div> <li>不要只靠 <code>display: block或width/height想“撑开”定位上下文,无效 - 如果父容器本身是
flex或grid项,仍需显式加position: relative -
content: ""是硬性要求,漏写就完全不渲染 - 推荐用
inset: 0替代top: 0; left: 0; right: 0; bottom: 0,更简洁且兼容性一致 - 遮罩色用
background-color: rgba(0, 0, 0, 0.5),别用opacity: 0.5——后者会让整个伪元素变透,包括可能叠加的图标或文字 - 如果图片用了
object-fit: cover或圆角,加overflow: hidden到父容器,否则遮罩可能超出裁剪区域 - 写
transition: opacity 0.3s ease在伪元素上,再用:hover::before { opacity: 1 } -
::before不能包含子节点,所以无法直接塞<span></span>或<button></button>;需要交互内容时,得换成真实<div class="overlay"> <li>遮罩层默认会拦截鼠标事件,加 <code>pointer-events: none可透传点击,但此时 hover 动画也失效——得把 hover 绑在父容器上
伪元素遮罩层怎么写才不漏、不溢出?
::before 必须同时满足:有 content: ""、绝对定位铺满、用 rgba() 而非 opacity 控制透明度。
hover 动画和交互要注意什么?
过渡动画要单独作用于伪元素的 opacity,而不是父容器或图片本身;若需在遮罩上放按钮或文字,::before 就不够用了。
最容易被忽略的是:伪元素遮罩对图片加载失败无感知,img 加载失败时,遮罩依然固执地盖着空白区域,视觉上就是一块黑灰块。真要健壮,得配合 img 的 onerror 事件切换 class 或 JS fallback。











