SVG的linearGradient天生是矢量实现,图形未显示渐变主因是漏写<defs>标签——浏览器将渐变视为资源而非图形元素,未包裹在<defs>内即被忽略而填默认色;必须确保<defs>位于<svg>内且在引用图形之前,ID大小写、英文括号及作用域须严格匹配。

SVG 的 linearGradient 本身是矢量实现,不用“转成矢量”,它天生就是——只要写法合规,缩放、旋转、响应式都不会糊。
为什么图形没显示渐变?90% 是漏了 <defs>
浏览器把 <linearGradient> 当作资源,不是图形元素;不包在 <defs> 里,就直接被忽略,图形填默认色(常是黑或透明)。
-
<defs>必须出现在<svg>根标签内,且要在所有引用它的图形(如<rect>、<path>)之前 - 不能写成
<svg><linearGradient>...</linearGradient><rect fill="url(#g)"></rect></svg>—— 这种写法无效 - 如果 SVG 是通过
<img src="icon.svg">引入的,外部 HTML 里的<defs>不会被识别,渐变必须定义在 SVG 文件内部
x1/y1/x2/y2 用百分比还是数值?
用百分比(如 x1="0%")更安全。像素值(如 x1="10")在容器缩放、viewBox 变化或响应式布局下容易错位,导致渐变方向“跑偏”。
-
x1="0%" y1="0%" x2="100%" y2="0%"→ 水平左到右 -
x1="0%" y1="0%" x2="0%" y2="100%"→ 垂直上到下 -
x1="0%" y1="0%" x2="100%" y2="100%"→ 对角左上到右下 - 若需固定物理长度(比如只在图标内部渐变 20px),才考虑
gradientUnits="userSpaceOnUse"配合像素值,但多数 UI 场景不需要
fill="url(#id)" 不生效?检查这三处硬性匹配
ID 大小写、括号、作用域,三者错一个,渐变就断掉。
立即学习“前端免费学习笔记(深入)”;
- ID 名称严格大小写敏感:
url(#MyGrad)≠url(#mygrad) - 括号必须是英文半角:
url(#grad)✅,url(#grad)❌(中文括号) - 内联 SVG 中,
<defs>和图形必须在同一个<svg>标签内;跨<svg>标签无法共享 ID - 调试技巧:先给图形设个纯色
fill="hotpink"确认它渲染出来了,再换回url(#xxx)
<stop> 的 offset 超出 0–100% 会怎样?
不会报错,但超出部分被静默截断——只在 [0%, 100%] 区间插值,首尾颜色会被“撑满”,容易误判为渐变失效。
-
<stop offset="-20%" stop-color="white"/>→ 实际从 0% 开始用白色 -
<stop offset="120%" stop-color="black"/>→ 实际到 100% 就结束,黑色只在终点体现 -
offset必须单调递增,否则行为未定义(Chrome 可能重排,Firefox 可能跳过) - 多个
<stop>可精细控制过渡节奏,例如offset="0% / 30% / 70% / 100%"
真正容易被忽略的是:渐变定义本身不参与渲染流程,也不触发 layout,但它对坐标系和单位极其敏感——gradientUnits 默认是 objectBoundingBox(归一化到图形包围盒),一旦你手动改了 viewBox 或加了 transform,又没同步调整 gradientUnits 或坐标值,视觉偏差就来了。



















