直接用background多层叠加更稳更轻;伪元素易因content缺失、尺寸塌缩、cover错位、Safari兼容等问题出错;仅需动画控制、错位蒙版或IE9兼容时才用::after。
直接用 background 多层叠加比 ::after + position: absolute 更稳、更轻、更少坑。 除非你要做动画过渡、响应式错位遮罩,或者必须兼容 IE9 及更早版本,否则没必要绕路写伪元素。
很多人一想到“在图片上盖一层渐变”,第一反应是给容器加 position: relative,再用 ::after 绝对定位盖上去。这看似直观,但实际踩坑密集:
::after 必须写 content: "" 才能渲染,漏掉就白忙活top: 0; left: 0; right: 0; bottom: 0 看似填满,但若父容器没设 height 或含流式内容,它可能塌缩成 0 高background-size: cover 在伪元素里行为不稳定——尤其当图片宽高比和容器不一致时,cover 会各自裁剪,导致渐变层和底图错位::after 的 background-blend-mode 支持不全,叠加色可能发灰或失效background 多层写法的正确顺序与尺寸控制浏览器把逗号分隔的多个值当作独立图层,从左到右、从前到后堆叠。渐变要盖在图片上,就得写在前面:
background: linear-gradient(to bottom, rgba(0,0,0,0.6), transparent), url('bg.jpg');
但光这样远远不够——background-size 和 background-position 默认作用于所有层,而渐变没有“原始尺寸”,会强行拉伸,把图片也带变形。必须显式按层指定:
立即学习“前端免费学习笔记(深入)”;
background-size: 100% 100%, cover → 第一组对应渐变(填满),第二组对应图片(等比缩放)background-position: top, center → 渐变锚点在顶部,图片居中,避免黑条只盖左上角background-repeat: no-repeat 就以为对齐了——没设 background-position,两层的“中心”根本不在一起::after 方案只有三类情况值得绕开多背景,硬上伪元素:
opacity 动画(比如 hover 时淡入),而多背景的 opacity 无法单独控制某一层::after 模拟即便如此,也要加 z-index: 1 显式提层,并用 transform: translateZ(0) 触发硬件加速,防止 iOS Safari 渲染撕裂。
不是透明度调太低,也不是渐变方向不对,而是——background-position 没对齐。渐变默认从容器左上角开始计算,图片默认居中;结果你看到的“半边黑半边亮”,其实是两层偏移了。临时加 background-color: red 只能看是否渲染,真正要验证对齐,得用开发者工具逐层勾选 background-image,观察两个图层的起始点是否重合。