直接给body加opacity会使所有内容变透明;应使用::before伪元素单独控制背景透明度,或用rgba渐变叠加background-blend-mode实现半透背景效果。

直接给 body 或容器加 opacity 会连内容一起变透明
这是最常见的误操作:在 CSS 里写 body { opacity: 0.7; background-image: url(...); }。结果文字、链接、所有子元素都变半透明了——opacity 是作用于整个元素及其后代的,不能只透背景。
用 ::before 伪元素单独控制背景层
真正可控的方式是把背景图抽成一个独立的、仅负责展示的层,再对其设置透明度。推荐在 body 或某个全屏容器上使用伪元素:
body {
margin: 0;
min-height: 100vh;
position: relative;
}
<p>body::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url("bg.jpg");
background-size: cover;
background-position: center;
opacity: 0.4; /<em> 只影响这张图 </em>/
z-index: -1;
}-
z-index: -1确保它垫在内容底下,不影响点击和布局 - 必须设
content: "",否则伪元素不渲染 - 如果页面有滚动,建议把
::before挂在html上,或加background-attachment: fixed避免背景随滚动“滑走”
用 rgba() 渐变叠在图片上模拟“半透背景”效果
如果只是想让背景看起来更柔和、降低干扰,比纯 opacity 更自然的做法是叠加一层半透色块:
body {
background: linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), url("bg.jpg");
background-blend-mode: overlay;
background-size: cover;
}- 两个背景层用逗号分隔,前者是
rgba()渐变(这里用了纯色渐变),后者是图片 -
background-blend-mode控制混合方式,overlay、multiply或soft-light都可尝试 - 这种方法不会影响子元素,且兼容性比伪元素更好(IE11+ 支持)
注意图片本身带 alpha 通道时的叠加表现
如果你用的是 PNG 或 WebP 这类支持透明的格式,又叠加了 opacity 或 rgba 层,实际透明度是相乘关系(比如图片自带 80% 不透明 + 伪元素 opacity: 0.5 → 最终不透明度为 0.8 × 0.5 = 0.4)。调试时容易误判原因,建议先用 JPG 测试逻辑是否正确,再换透明格式微调。
立即学习“前端免费学习笔记(深入)”;


















