svg滤镜需先声明后调用,核心是filter元素内按序组合fegaussianblur、feoffset、femerge等原语;失效主因是目标元素无尺寸、filter未置于svg defs中、或url(#id)与id不严格一致。

SVG filter 元素本身不直接“添加效果”,它只是个容器;真正起作用的是里面一个个 feGaussianBlur、feOffset、feMerge 这类滤镜原语——漏掉任一环,效果就出不来。
为什么 filter: url(#blur) 写对了却没反应
90% 的失效不是代码写错,而是卡在三个硬性前提上:
- 目标元素必须有明确尺寸(
display: block或带width/height),<img>默认 inline,没宽高就静默失败 -
<filter></filter>必须嵌套在<svg></svg>的<defs></defs>里,单独扔在 HTML body 里无效 -
url(#blur)中的blur必须和<filter id="blur"></filter>完全一致:大小写、空格、引号一个都不能差;url(#Blur)和url(#blur)是两个不同滤镜
feGaussianBlur + feOffset + feMerge 搭出真实阴影
别用 filter: drop-shadow() 做 SVG 阴影——它兼容差、控制弱。原生 SVG 滤镜链才是正解:
-
in="SourceAlpha"是关键:只取图形轮廓(Alpha 通道)做模糊,否则会糊掉整个图形本体 -
<feoffset dx="2" dy="2"></feoffset>把模糊后的轮廓平移,形成阴影偏移 -
<femerge></femerge>合并两层:<femergenode in="SourceGraphic"></femergenode>(原图)+<femergenode in="offsetBlur"></femergenode>(阴影),顺序决定谁在上 - 记得显式设
<filter x="-20%" y="-20%" width="140%" height="140%"></filter>,否则大模糊值(如stdDeviation="10")会被默认区域裁掉边缘
stdDeviation 不是像素值,但得按经验调
这个值控制高斯函数的标准差,和视觉模糊程度非线性相关:
-
stdDeviation="1":几乎看不出变化,仅柔化锯齿 -
stdDeviation="3–5":适合文字描边或轻量图标阴影 -
stdDeviation="8–12":背景虚化常用范围,Mac 上表现稳定 -
stdDeviation="20+":Android 低端机易卡顿,且模糊扩散不可控;双参数写法stdDeviation="3 8"可模拟运动模糊
组合多个滤镜时,in 和 result 必须配对
滤镜链是线性流水线,每一步的输出靠 result 命名,下一步靠 in 引用:
- 写
<fegaussianblur in="SourceGraphic" stddeviation="4" result="blurred"></fegaussianblur>后,下一条必须用in="blurred"才能接上 -
result名字不能重复,也不能跨<filter></filter>使用——<filter id="a"></filter>里定义的result="x",<filter id="b"></filter>里不能in="x" - 漏写
in属性(比如只写<fegaussianblur stddeviation="4"></fegaussianblur>)会导致浏览器按默认行为处理,结果不可预测,常见为黑块或无效果
最容易被忽略的是:SVG 滤镜不修改元素几何尺寸,模糊/阴影都严格限制在 filter 的 x/y/width/height 范围内——哪怕你加了 feOffset,超出部分照样被裁,不是“看不见”,是根本没渲染。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











