首页 > 解决方案 > 如何在文本上使用 css 背景过滤器?

问题描述

我正在尝试从 Apples Aracde 网站重新创建这种效果: https ://www.apple.com/apple-arcade/ 查看“播放非凡”文本,它应用了背景过滤器并模糊了它背后的视频。

我可以看到他们使用 SVG 作为蒙版来剪辑背景,但我似乎不能这样做,文本被拉伸或倒置。

谁能告诉我如何使用文本作为 SVG 蒙版来剪切带有背景过滤器的 div/元素?

有问题的项目截图: https ://i.imgur.com/WHZO8Yj.png

标签: htmlcsssvg

解决方案


据我所知,没有办法直接将 应用于backdrop-filter:blur文本元素。



第一个解决方案:最慢的一个

  1. 创建一个容器
  2. 为其应用背景(或其 ::before 伪元素)
  3. 使用 filter:blur 使容器的背景模糊
  4. 将 svg 蒙版应用到 svg 元素上,然后将相同的背景应用到容器(或其 ::before 伪元素)

这样,我们在顶部有模糊的背景,在它下面有非模糊的版本。

注意:将背景应用到容器的 ::before 伪元素将允许您在不触及 svg 蒙版的情况下修改背景(如果您需要翻转背景以创建更多对比度但无法修改原始图像,则很有用)。

第二种解决方案:最快的一个

  1. 创建一个容器
  2. 为其应用背景
  3. 创建一个代表我们的“文本”的 svg 元素
  4. 将背景过滤器:模糊应用于 svg 元素
  5. 将 svg-mask 应用到 svg 元素

这样我们就有了如果背景过滤器:模糊可以应用于文本的效果。
这是表现最好的一个,因为它是唯一不需要 svg 元素复制背景的方法(由于 background-attachment:fixed 属性,必须在每一帧重新绘制)。

第三种解决方案:最兼容的一个

(需要有2份背景,其中一份已经模糊)

  1. 创建一个容器
  2. 为其应用背景
  3. 创建一个代表“文本”的 svg 元素
  4. 将背景的模糊版本应用到 svg 元素
  5. 将 svg-mask 应用到 svg 元素

伟大的!但是对比度太低了...

让我们添加一个阴影吧!

单独应用模糊效果会给我们带来低对比度(难以阅读文本)。
为了解决这个问题,我对 svg 应用了阴影:

  1. 在文档中创建一个 svg 元素
  2. <defs>标签内创建一个带有<filter>标签的过滤器并给它一个唯一的ID
  3. 在标签内使用您选择的 a<filter>创建 a (4 和 5 是很好的初始数字)<feGaussianBlur>stdDeviation
  4. 仍在标签内,使用运算符<filter>创建一个并设置为<feComposite>outin2SourceGraphics
  5. 为了塑造我们的影子,我们将使用标签的<image>外部<defs>
  6. 将's属性设置url为与标签相同的 id (参见上面的第 2 点)<image>filter<filter>
  7. xlink:href属性的值设置为与您的 svg 路径相同的值

这是参考代码:

<svg>
  <defs>
    <filter id = "trans-shadow">
      <feGaussianBlur stdDeviation = "5"/>
      <feComposite operator = "out" in2 = "SourceGraphic"/>
    </filter>
  </defs>
  <image filter = "url(#trans-shadow)" x = "0" y = "0" width = "100%" height = "100%" xlink:href = "./SVG.svg" />
</svg>

现场演示https ://cristiandavideconte.github.io/applyBackdropFilterBlurToText/
源代码https ://github.com/CristianDavideConte/applyBackdropFilterBlurToText

我会给你一个代码片段,其中包含前 2 个解决方案(一个已注释),所以你可以选择哪一种更适合您:

  <html>
  <head>
    <style>
        html,body {
            margin: 0;
            /* UNCOMMENT THIS PART TO TRY OUT THE NON-REVERSED VERSION
            background: url(https://wallpaperhd.wiki/wp-content/uploads/wallpapers-1920x1080-5ae1cd66635d3.jpg) 0 0;
            background-repeat: no-repeat;
            background-attachment: fixed;
            */
        }

        /* DELETE THE ::before TO TRY OUT THE NON-REVERSED VERSION */
        .container::before {
          content: "";
          z-index: -1;
          position: absolute;
          width: 100vw;
          height: 200vh;
          background: url(https://wallpaperhd.wiki/wp-content/uploads/wallpapers-1920x1080-5ae1cd66635d3.jpg) 0 0;
            background-repeat: no-repeat;
            background-attachment: fixed;
          transform: rotateY(180deg);
        }

        .container {
                width: 100vw;
                height: 200vh;
                display: flex;
                align-items: center;
        }

        .svg {
            position: absolute;
            z-index: 1;
            width: 100%;
            height: 100%;

            /* DELETE THIS 4 LINES TO TRY OUT THE NON-REVERSED VERSION */
            filter: blur(20px) saturate(180%);
            background: url(https://wallpaperhd.wiki/wp-content/uploads/wallpapers-1920x1080-5ae1cd66635d3.jpg);
            background-repeat: no-repeat;
            background-attachment: fixed;

            /* UNCOMMENT THIS PART TO TRY OUT THE NON-REVERSED VERSION
            backdrop-filter: blur(20px) saturate(180%);
            */

            /* Chrome, Safari and all webkit browsers */
            -webkit-mask-image: url(./SVG.svg);
            -webkit-mask-size: contain;
            -webkit-mask-position: center;
            -webkit-mask-repeat: no-repeat;
            -webkit-mask-border: url(./SVG.svg) 25;

            /* FIREFOX */
            mask-image: url(./SVG.svg);
            mask-size: contain;
            mask-position: center;
            mask-repeat: no-repeat;
            mask-border: url(./SVG.svg) 25;
        }
    </style>
</head>

<body>
    <section class = "container">
        <div class = "svg"></div>
    </section>
</body>
</html>

为了让这个片段工作,您需要将 svg 掩码称为 SVG.svg,并且它必须与您的 html 文件放在同一个文件夹中。

请记住,您无法从本地存储访问掩码 url 的 svg 文件,您需要一个服务器(node.js 很好)。

在这里,您有2个可能结果的屏幕截图:

方法 3 - 无阴影:方法 2 - 有阴影:


推荐阅读