CSS如何制作悬停时的半透明遮罩过渡

0次阅读

正确做法是用伪元素::before 或::after 叠加半透色块并单独控制 opacity 过渡,需设父元素 position: relative、伪元素 content 和 overflow: hidden,避免影响子元素及触发重排。

CSS 如何制作悬停时的半透明遮罩过渡

hover 时用 opacity 实现遮罩过渡,但别直接改父元素

直接对包含图片和文字的容器设 opacity,会导致整个子内容(包括文字)一起变透明,这不是遮罩,是“褪色”。真正要的是只盖一层半透色块,且过渡平滑。

正确做法是用伪元素 ::before::after 叠在内容上方,单独控制它的透明度和过渡:

img {position: relative;   display: block;} img::after {content: '';   position: absolute;   top: 0; left: 0; right: 0; bottom: 0;   background: rgba(0, 0, 0, 0.6);   opacity: 0;   transition: opacity 0.3s ease; } img:hover::after {opacity: 1;}
  • 必须给父元素(如 imgdiv)加 position: relative,否则 ::after 会相对 body 定位
  • backgroundrgba() 而非 opacity,避免影响子元素;opacity 只用来做显隐过渡
  • 过渡时间别设太长,0.2s–0.4s 是人眼感知自然的区间,超过 0.5s 就像卡顿

用 transform + opacity 组合避免重排重绘

opacity 过渡虽简单,但在某些旧版 Chrome 或 Safari 下可能有闪烁。更稳的方式是加上 transform: translateZ(0) 强制 GPU 加速,或用 scale 配合透明度微调视觉节奏。

例如让遮罩“浮现”而非硬切:

立即学习 前端免费学习笔记(深入)”;

.card::before {content: '';   position: absolute;   top: 0; left: 0; right: 0; bottom: 0;   background: rgba(0, 0, 0, 0.7);   opacity: 0;   transform: scale(0.95);   transition: opacity 0.25s ease, transform 0.25s ease; } .card:hover::before {opacity: 1;   transform: scale(1); }
  • 只对 opacitytransform 做 transition,这两者不触发 layout,性能好
  • 避免在 hover 中改 widthheighttopleft 等会触发布局计算的属性
  • 如果容器本身有 border-radius,记得给伪元素也加相同值,否则圆角内会出现像素级错位

IE11 兼容:filter 替代 opacity + 降级处理

IE11 不支持 opacity 在伪元素上的过渡,但支持 filter: alpha(opacity=0)。不过它和 transform 冲突,得单独处理。

稳妥写法是用特性检测或直接写两套规则:

.cover::before {opacity: 0;   transition: opacity 0.3s;} @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {.cover::before {     opacity: 1;     filter: alpha(opacity=0);     transition: none;   }   .cover:hover::before {filter: alpha(opacity=70);   } }
  • @media 查询里那段是 IE10+ 的 hack,不是所有构建工具都支持,上线前务必实测
  • 别依赖 filter: blur() 做遮罩模糊效果——IE 不支持,且现代浏览器中它开销大、易糊边
  • 如果项目已放弃 IE,这段可全删;但凡还有 1% IE 流量,就得留个兜底,哪怕只是静默降级为无动画

遮罩文字层被 pointer-events 拦住怎么办

遮罩层盖上去后,下面的按钮或链接点不动了?默认 ::before 会拦截鼠标事件,即使它是半透明的。

最简解法是加一行 pointer-events: none 到伪元素上:

.item::before {pointer-events: none;   /* 其他样式…… */} .item:hover::before {pointer-events: auto; /* 只有 hover 时才需要响应,比如点击遮罩关闭弹窗 */}
  • 多数场景下遮罩只是视觉层,不需要交互,所以全程 none 就够了
  • 如果遮罩本身要响应点击(比如关掉浮层),就只在 hover 状态设 auto,否则用户移开鼠标后还残留点击区域
  • 别给父容器设 pointer-events: none 来“绕过”,那会把底下所有可点击内容一并禁用

实际写的时候最容易漏的是伪元素的 contentposition,少一个就啥都不显示;还有就是忘了给父容器设 overflow: hidden,导致遮罩溢出圆角或边框。这些地方没报错,但效果直接消失,查起来反而最费时间。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-14发表,共计2061字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources