SVG作为可缩放矢量图形格式,天然适合在网页中呈现清晰且体积小的图形。除了静态展示,SVG还支持多种原生动画实现方式,开发者可以不借助庞大框架就让图形产生位移、缩放、变色等动态效果。常用的手段主要有三类:基于SMIL的标签动画、基于CSS的样式动画,以及用JavaScript控制SVG属性。

一、使用SMIL标签实现动画
SMIL(Synchronized Multimedia Integration Language)是一套基于XML的同步多媒体语言,SVG直接内嵌了它的动画元素。最常见的是<animate>、<animateTransform>和<animateMotion>。这类方式最大的特点是:动画逻辑写在SVG文件内部,不依赖外部样式或脚本,非常适合做独立的动态图标。
例如,让一个圆形在两点之间水平移动,可以用下面的代码。其中attributeName指定要变化的属性,from和to描述起止值,dur设定时长,repeatCount控制重复次数。
<svg width="200" height="100" viewBox="0 0 200 100">
<circle cx="20" cy="50" r="15" fill="tomato">
<animate attributeName="cx"
from="20"
to="180"
dur="2s"
repeatCount="indefinite" />
</circle>
</svg>
除了基础属性,<animateTransform>能处理平移、旋转、缩放等变换。下面的例子让一个矩形不停旋转,type="rotate"表示变换类型,values以分号分隔角度与中心坐标。
<svg width="120" height="120" viewBox="0 0 120 120">
<rect x="50" y="50" width="20" height="20" fill="seagreen">
<animateTransform attributeName="transform"
type="rotate"
values="0 60 60;360 60 60"
dur="3s"
repeatCount="indefinite" />
</rect>
</svg>
SMIL的优点是声明式、易读,不需要写JS就能完成复杂路径动画;缺点是部分旧版IE不支持,且当动画需要和页面其他逻辑深度交互时,控制能力不如脚本。Chrome曾宣布弃用又恢复,目前主流浏览器基本可用,但新项目建议评估长期维护成本。
二、通过CSS动画驱动SVG
由于SVG元素也是DOM节点,我们可以像给普通HTML元素加样式那样,用CSS的@keyframes和animation属性让SVG动起来。这种方式和页面整体样式系统一致,方便统一调整主题与响应式规则。
下面演示一个用CSS让SVG线条虚线流动的效果。我们在样式里定义stroke-dashoffset从有到无,形成蚂蚁线般的动态感。
<style>
.dash-line {
stroke: #3366cc;
stroke-width: 4;
stroke-dasharray: 10 6;
animation: flow 1s linear infinite;
}
@keyframes flow {
to { stroke-dashoffset: -16; }
}
</style>
<svg width="200" height="60">
<line class="dash-line" x1="10" y1="30" x2="190" y2="30" />
</svg>
CSS动画的优势在于性能通常由合成线程处理,配合will-change可优化;也能轻松通过媒体查询在移动端减速或关闭。但它只能操作能被CSS控制的属性,像某些SVG专有属性(如d路径的复杂插值)旧浏览器支持有限。对于简单变色、位移、旋转,CSS是首选。
三、JavaScript控制SVG动画
当动画要根据用户点击、数据变化或滚动位置触发时,用JavaScript直接修改SVG属性或使用Web Animations API更灵活。下面例子用requestAnimationFrame让圆跟随鼠标水平位置移动。
const svg = document.querySelector('svg');
const circle = svg.querySelector('circle');
svg.addEventListener('mousemove', (e) => {
const rect = svg.getBoundingClientRect();
const x = e.clientX - rect.left;
circle.setAttribute('cx', x);
});
这种方案把动画逻辑完全交给脚本,可与状态管理、接口数据绑定。缺点是代码量相对大,需要自己处理缓动与性能。如果仅做装饰性循环动画,优先用前面两种声明式方案更省力。
四、方案对比与选择建议
为方便选型,我们把三种方式在几个维度做简单比较:
| 实现方式 | 是否需要JS | 交互控制力 | 兼容性 |
|---|---|---|---|
| SMIL标签 | 否 | 弱 | 现代浏览器支持,IE不支持 |
| CSS动画 | 否 | 中 | 非常好 |
| JavaScript | 是 | 强 | 取决于API,普遍良好 |
实际开发中,若交付的是一个独立SVG动图(如loading),用SMIL最紧凑;若是大型站点里的图标动效,用CSS更易维护;涉及图表实时刷新则用JS。理解SVG标签如何承载动画,能让你在无需重型依赖时依然做出流畅视觉效果。
SVGSMILCSS_animation修改时间:2026-07-31 14:39:29