直接用linear-gradient()通过::before伪元素加蒙层最干净:父容器需position: relative,伪元素设content: ""、宽高100%、background: linear-gradient(to bottom, rgba(0,0,0,0.6), transparent),hover时仅调opacity并加transition。

直接用 linear-gradient() 叠在图片上就能做蒙层,不用 JS、不改 HTML 结构,但必须用伪元素或额外容器包裹,且 rgba() 的 alpha 值必须写小数(如 0.6),写 70% 会失效。
用 ::before 伪元素加蒙层(推荐)
这是最干净、无侵入的方式:不新增 DOM,纯靠 CSS 控制。前提是图片得包在一个有定位的容器里。
-
.img-container必须设position: relative,否则::before无法绝对覆盖 -
::before要显式写content: "",否则不渲染 - 尺寸必须设为
width: 100%; height: 100%,不能靠inset: 0(部分 Safari 版本不认) - 渐变方向建议用
to bottom这类关键词,比0deg更直观;rgba(0,0,0,0.6)中的0.6不能写成60%
.img-container {
position: relative;
display: inline-block;
}
.img-container::before {
content: "";
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background: linear-gradient(to bottom, rgba(0,0,0,0.6), transparent);
}
用 background-image 多层叠加(适合背景图)
如果图片本身就是元素的 background-image(比如 div 设置了背景图),那可以直接在同一属性里叠一层渐变,顺序很重要:渐变在前,图片在后。
- 写法必须是
background-image: linear-gradient(), url(...),反过来图片就看不见了 - 渐变层必须含透明色(如
transparent或rgba(0,0,0,0)),否则盖死图片 - 别加
background-attachment: fixed—— iOS Safari 滚动时容易错位或闪烁,不是性能问题,是 WebKit 渲染 bug - 记得配
background-size: cover,否则渐变尺寸可能和图片不匹配
.hero {
background-image: linear-gradient(to top, rgba(0,0,0,0.4), transparent), url("banner.jpg");
background-size: cover;
background-position: center;
}
为什么不用 mask-image?
虽然 mask-image: linear-gradient() 才是语义上真正的“遮罩”,但它在实际项目中基本不可用。
- Safari 直到 15.4+ 才稳定支持,旧版 iOS WebKit 会失效
- Firefox 截至 2026 年中仍完全不支持
mask-image的渐变值 - Chrome 需要
-webkit-mask-image前缀,且和标准写法不能共存 - 一旦用错,整个元素内容消失,连 fallback 都难加
hover 动态蒙层怎么写?
直接改伪元素的 opacity 或 background 即可,不需要 JS。
- 不要写
.img-container:hover::before { background: ... }再重复一遍渐变 —— 浏览器重绘开销大,尤其在移动端 - 更轻量的做法是只调
opacity:.img-container:hover::before { opacity: 0.3; } - 如果想变色,优先改
background中的 rgba 值,而不是换整个渐变函数 - 务必加
transition: opacity 0.3s ease,否则变化生硬
真正容易被忽略的是:所有渐变蒙层都依赖容器尺寸和定位上下文。没有 position: relative 的父容器,::before 就会相对于 body 定位;图片用了 object-fit: cover 但容器没设宽高,蒙层就会拉伸变形——这些不会报错,只会让效果“看起来差不多但不对”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











