遮罩层过渡效果可用伪元素+transition+定位实现,但需满足五点硬性条件:父容器position: relative、::after有content: ""、absolute定位覆盖全图、用rgba背景色而非opacity、transition写在常态规则中。

遮罩层过渡效果不用 JS 也能做,关键在伪元素 + transition + 定位组合,但写错一行就完全不显示。
为什么直接给 <img> 加 opacity 不行
常见错误是写 .my-img:hover { opacity: 0.4; }——这会让整个图片(包括文字、按钮、图标)一起变淡,违背“只压背景、不干扰内容”的设计意图。opacity 作用于整棵 DOM 子树,无法局部控制。更糟的是,如果图片没设 display: block 或父容器没设 overflow: hidden,hover 可能根本触发不了。
::after 伪元素实现遮罩的硬性条件
必须同时满足以下五点,缺一不可:
- 父容器设
position: relative,否则::after会相对<body>定位 -
::after必须有content: "",漏写就等于没声明这个伪元素 -
::after要用position: absolute+top/left/right/bottom: 0覆盖全图 - 透明度必须用
background-color: rgba(0,0,0,0.5),不是opacity(后者会透出下层内容) -
transition: opacity 0.3s ease必须写在常态规则里,不能只写在:hover中
遮罩层要放文字或按钮时怎么处理
伪元素不支持嵌套子节点,::after 里塞不了 <h3> 或 <button>。这时候得换真实 DOM:
立即学习“前端免费学习笔记(深入)”;
- 用
<div class="overlay"><h3>标题</h3></div>替代伪元素 - 给遮罩层加
pointer-events: none,让鼠标穿透到图片上(除非你明确要拦截点击) - 若需点击遮罩触发行为(如播放视频),再单独加
pointer-events: auto到对应子元素 - 避免对
<img>设z-index,它默认是auto层级,真实<div>靠position: absolute就能压上去
移动端和响应式容易忽略的细节
桌面看着好好的遮罩,到手机上常出现错位、不覆盖、动画卡顿等问题:
- 图片宽高要用
width: 100%; height: auto或aspect-ratio,别写死像素值 - 遮罩层的
top/left/right/bottom: 0在缩放后可能失效,建议加transform: translateZ(0)强制硬件加速 - iOS Safari 对
transition的 timing function 敏感,cubic-bezier(0.22, 0.61, 0.36, 1)比ease-in-out更稳 - 小屏上遮罩文字容易被截断,加
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;控制
最常被跳过的一步:没测过首次加载时的初始状态。比如视频遮罩默认该显示还是隐藏?伪元素的 opacity: 0 是否在页面渲染完成前就已生效?这些不验证,上线后第一眼就是 bug。



















