不久前我不得不对这个问题进行彻底的研究,并提出了一个非常灵活的解决方案,尽管对于某些人的需求来说这可能有点过头了。我不仅需要模糊图像,还需要各种图像的动态模糊半径、叠加颜色和叠加不透明度。我还需要选择只模糊背景中的图像,并在其上覆盖其他元素。这是我能够创建的最佳跨浏览器(和高性能)解决方案。
首先,我手头有一个 SVG,名称为 blur.svg 并不令人鼓舞。它应用了模糊过滤器,如果仔细观察,stdDeviation(设置模糊半径)实际上是通过传入参数以编程方式设置到请求资产的 URL 的。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="blur">
<feGaussianBlur stdDeviation="#{params[:blur]}" />
</filter>
</svg>
然后我有一个 SCSS mixin,它允许向任何包装器添加模糊覆盖,具有可自定义的模糊半径、覆盖颜色和覆盖不透明度。
@mixin background_blurred($blur_radius:4, $overlay_color:white, $overlay_opacity:0.6) {
position: relative;
.background_blurred {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
filter: url('blur.svg#blur?blur=#{$blur_radius}');
filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='#{$blur_radius}');
transform: translateZ(0);
&:after {
content: '';
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: $overlay_color;
opacity: $overlay_opacity;
}
}
.foreground {
width: 100%;
height: 100%;
position: relative;
z-index: 2;
}
}
您可能想知道为什么我添加了transform: translateZ(0);。唯一的效果是在渲染上强制硬件加速以保持性能。您可能还想知道为什么没有供应商前缀。如果你愿意,你可以在CanIUse 上查找filter 之类的东西,但我在这个项目上使用了autoprefixer 来替我担心这些事情。当然,为什么要使用这个 SVG 进行过滤,而不是像 blur(4px) 这样的东西呢?那不是更容易吗?会的,但 Firefox(截至撰写时)仅支持带有 URL 的 filter 属性。
然后您可以将模糊混合应用到包装类:
.my_wrapper_class {
@include background_blurred(3, #f9f7f5, 0.7);
}
请注意,对于此方法,我们必须使用在样式属性中设置自定义背景的类,而不是带有 src 的图像标签。您可以调整背景位置并根据自己的喜好覆盖背景大小。
<div class="my_wrapper_class">
<div class="background_blurred" style="background: url('URL OF IMAGE TO BLUR') no-repeat; background-position: 50% 0;"></div>
<div class="foreground">
<p>Stuff that should appear above the blurred background and not be blurred.</p>
</div>
</div>