You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅对背景图片应用CSS filter滤镜而不影响子元素?

问题描述

我制作了一个全屏滚动(scroll-snap)的HTML页面,页面包含多个上下排布的主题板块,可通过向下滚动查看。不同板块通过background-image: url("image.png")标签设置了不同的背景图片。

我的代码如下:

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <style>
        body, html {
            height: 100%;
        }
        body {
            background-color: black;
        }

        .slides {
            height: 100%;
            overflow: scroll;
            overflow-x: hidden;
            scroll-snap-type: y mandatory;
        }

        .slide {
            height: 100%;

            background-attachment: fixed;
            background-position: center;
            background-repeat: no-repeat;
            background-size: cover;

            scroll-snap-align: start;
        }
        
        .home {
            background-image: url("/img/bg.jpg");
        }
        .band {
            background-image: url("/img/bg2.jpg");
        }
        .pictures {
            background-image: url("/img/bg3.jpg");
        }
    </style>
</head>
<body>
    <div class="slides">
        <div class="slide home"></div>
        <div class="slide band"></div>
        <div class="slide pictures"></div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</html>

当我尝试使用以下代码应用滤镜时:

filter: brightness(60%) blur(4px);
-webkit-filter: brightness(60%) blur(4px);

滤镜会模糊div内的所有子元素,而非仅背景图片。我曾尝试使用backdrop-filter但未成功,现寻求可行的解决方法。


解决方案

方法一:利用伪元素承载背景与滤镜

把背景图移到.slide的::before伪元素上,给伪元素设置滤镜,同时通过定位让伪元素成为底层背景,不影响上层内容。

修改后的CSS代码:

body, html {
    height: 100%;
}
body {
    background-color: black;
}

.slides {
    height: 100%;
    overflow: scroll;
    overflow-x: hidden;
    scroll-snap-type: y mandatory;
}

.slide {
    height: 100%;
    scroll-snap-align: start;
    /* 让伪元素相对于当前slide定位 */
    position: relative;
    overflow: hidden;
}

.slide::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-attachment: fixed;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    /* 应用目标滤镜 */
    filter: brightness(60%) blur(4px);
    -webkit-filter: brightness(60%) blur(4px);
    /* 将伪元素置于底层 */
    z-index: -1;
}

.home::before {
    background-image: url("/img/bg.jpg");
}
.band::before {
    background-image: url("/img/bg2.jpg");
}
.pictures::before {
    background-image: url("/img/bg3.jpg");
}

方法二:嵌套div分离背景与内容

给每个.slide内部添加独立的背景div和内容div,滤镜仅作用于背景div,内容div通过定位叠在上方。

修改后的HTML结构:

<div class="slides">
    <div class="slide">
        <div class="slide-bg home"></div>
        <!-- 这里添加板块内容 -->
        <div class="slide-content">首页内容</div>
    </div>
    <div class="slide">
        <div class="slide-bg band"></div>
        <div class="slide-content">乐队介绍</div>
    </div>
    <div class="slide">
        <div class="slide-bg pictures"></div>
        <div class="slide-content">图片集</div>
    </div>
</div>

对应的CSS代码:

body, html {
    height: 100%;
}
body {
    background-color: black;
}

.slides {
    height: 100%;
    overflow: scroll;
    overflow-x: hidden;
    scroll-snap-type: y mandatory;
}

.slide {
    height: 100%;
    scroll-snap-align: start;
    position: relative;
    overflow: hidden;
}

.slide-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-attachment: fixed;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    filter: brightness(60%) blur(4px);
    -webkit-filter: brightness(60%) blur(4px);
    z-index: -1;
}

.home {
    background-image: url("/img/bg.jpg");
}
.band {
    background-image: url("/img/bg2.jpg");
}
.pictures {
    background-image: url("/img/bg3.jpg");
}

.slide-content {
    position: relative;
    z-index: 1;
    /* 可自定义内容样式,比如文字颜色、内边距 */
    color: #fff;
    padding: 2rem;
}

关于backdrop-filter无效的说明

backdrop-filter是对元素后方的内容应用滤镜,而非元素自身的背景图。如果你的.slide没有透明背景,或者后方没有其他可见内容,这个属性自然不会产生效果,因此它不适合处理自身背景图的滤镜需求。


内容的提问来源于stack exchange,提问作者Nickessss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 13:20:57