在SVG的所有绘图元素中,<path>是最强大也最常用的一个。矩形、圆形、多边形这些基础图形,本质上都可以用path画出来。而path的全部能力,都浓缩在它的d属性里——d是drawing的缩写,里面存放着一串绘图命令,浏览器读取这些命令后逐步描绘出图形轮廓。很多初学者看到d="M10 10 L90 90"这样的字符串会觉得无从下手,其实只要理解了命令的规则,写路径就像给机器人下指令一样简单。

d属性的基本语法和坐标规则
d属性的值由一系列命令组成,每个命令由一个字母加上若干个数字构成。字母大小写有明确含义:大写字母表示绝对坐标,坐标值直接对应画布上的位置;小写字母表示相对坐标,坐标值是相对于当前点(画笔当前位置)的偏移量。例如M 100 100表示把画笔移动到坐标(100,100),而m 100 100表示从当前位置向右移动100、向下移动100。
命令之间用空格或逗号分隔,数字之间的分隔符在大多数情况下可以省略,因为正负号本身就能起到分隔作用。比如"10-20"会被解析成10和-20两个数。但为了代码可读性,建议保留空格。另外,重复的命令字母可以省略,比如"L 10 10 20 20"等价于"L 10 10 L 20 20"。
还有一个容易忽略的细节:路径的起始点由M命令决定,如果d属性不以M或m开头,整个路径将被视为无效。画笔移动的概念很重要——M命令只是移动位置,不会留下笔迹,而后续的画线命令才会真正生成可见的线段。
直线类命令:M、L、H、V、Z
这五个命令负责绘制直线段,是构成多边形图形的基础。M(moveto)移动画笔到指定点;L(lineto)从当前点画直线到指定点;H(horizontal lineto)画水平线,只需一个x坐标;V(vertical lineto)画竖直线,只需一个y坐标;Z(closepath)闭合路径,从当前点画一条直线回到路径起点。
举个例子,画一个100×100的正方形:
<svg width="200" height="200"> <path d="M 50 50 H 150 V 150 H 50 Z" fill="none" stroke="black" stroke-width="2"/> </svg>
这段代码的含义是:移动到(50,50),水平画线到x=150,竖直画到y=150,再水平回到x=50,最后用Z闭合。H和V命令在画轴对齐的图形时比L更简洁,不容易出错。Z命令除了闭合图形,还有一个实际作用:如果设置了stroke-linejoin,闭合点处会有正确的拐角样式,而手动画回起点的L命令在起终点衔接处可能出现缝隙。
再看相对坐标的写法。同样一个正方形,用小写命令可以这样写:
<path d="m 50 50 h 100 v 100 h -100 z" fill="none" stroke="black"/>
相对坐标的好处是便于复用和调整位置,只需要修改开头的m命令,整个图形就能平移,内部结构不用动。在制作图标库时,这种写法非常实用。
曲线类命令:贝塞尔曲线与弧线
直线只能画多边形,要画平滑的曲线就需要贝塞尔曲线命令。SVG提供了两族曲线命令:C和S是三次贝塞尔曲线,Q和T是二次贝塞尔曲线。三次贝塞尔曲线的C命令需要三个坐标点:两个控制点加一个终点,格式为C x1 y1, x2 y2, x y。曲线从当前点出发,结束于终点,控制点像磁铁一样把曲线往自己的方向拉。
下面用三次贝塞尔曲线画一个近似的心形:
<svg width="200" height="200">
<path d="M 100 170
C 20 110, 20 40, 70 35
C 90 33, 100 50, 100 65
C 100 50, 110 33, 130 35
C 180 40, 180 110, 100 170"
fill="red"/>
</svg>这个心形由四段三次贝塞尔曲线拼接而成,左右对称。控制点的选取决定了曲线的弯曲程度和方向,通常需要反复调试。S命令是C的简写形式,它会自动把上一段曲线的第二个控制点关于当前点做镜像,作为新曲线的第一个控制点,这样写出的连续曲线更紧凑,适合绘制波浪线、飘带等图形。
二次贝塞尔曲线Q只需要一个控制点和一个终点,格式为Q x1 y1, x y。它的曲线形状比三次曲线简单,计算开销也小。T命令和S类似,自动镜像上一个控制点,两个命令交替使用可以画出流畅的对称曲线。画一个简单的波浪线示例:
<path d="M 20 100 Q 60 40, 100 100 T 180 100"
fill="none" stroke="blue" stroke-width="3"/>这里的T自动生成了(140,160)这个镜像控制点,让曲线先上弯再下弯,形成标准正弦波形状。
最后是弧线命令A,它是d属性中参数最多的命令,共七个参数:rx ry x-axis-rotation large-arc-flag sweep-flag x y。前两个是椭圆的半径,第三个是旋转角度,第四和第五个是标志位,最后是终点坐标。large-arc-flag决定画大弧还是小弧(1为大弧),sweep-flag决定顺时针还是逆时针(1为顺时针)。用弧线画一个完整的圆需要两段弧配合:
<path d="M 100 50
A 50 50 0 1 1 99.99 50
Z" fill="none" stroke="green" stroke-width="2"/>注意这里终点写的是99.99而不是100,因为起点和终点完全重合时,浏览器无法确定弧的方向,会退化成不画。实际开发中画圆一般直接用circle元素,A命令更多用于画扇形、圆角和部分圆弧。
实战技巧与常见坑
掌握了命令之后,再分享几个实用经验。第一,fill属性默认是黑色,如果你只是想画线条而路径没有闭合,浏览器会自动把首尾连起来填充,经常出现莫名其妙的黑色块。解决办法是设置fill="none"。第二,路径书写的顺序决定了正反方向,这在做路径动画和fill-rule时会影响最终效果。
第三,复杂图形不建议徒手写d属性。设计稿导出的路径往往有几十个命令,人工维护很困难。实际工作流通常是设计师在Illustrator或Figma里画好图形,导出SVG后再交给前端使用,必要时用SVGO这类工具压缩路径数据。手写路径的价值在于理解原理、绘制简单图形以及精确调整个别坐标点。
第四,调试路径时可以把d属性放到一个可视化工具里检查,比如浏览器的开发者工具选中path元素后,会高亮显示路径轮廓和控制点,非常直观。理解了M、L、H、V、Z、C、S、Q、T、A这一整套命令,你就掌握了SVG矢量绘制的核心,图标、Logo、图表线条、动画轨迹都能用一串简洁的命令描述出来。