SVG的<text>不支持自动换行,需用嵌套<tspan>并设置dy控制行距,配合text-anchor和dominant-baseline实现居中对齐,注意单位、继承及字体度量差异。

SVG <text> 本身不支持自动换行
SVG 的 <text> 是一个单行文本容器,不像 HTML 的 <div> 或 <p> 那样能根据宽度自动折行。直接写换行符 \n 或在 XML 中敲回车,浏览器会忽略——它只当空格或不渲染。
要实现“换行”,必须拆成多个 <text> 元素,或用 <tspan> 手动控制每行位置。
-
<tspan>必须嵌套在<text>内,不能单独存在 - 每行
<tspan>需显式设置y(或dy)来控制垂直偏移 - 推荐用
dy而非绝对y,避免重复计算基线
用 <tspan> 实现多行并居中对齐
对齐依赖两个层面:一是整段文本容器的定位(x/y),二是内部各行的水平对齐(text-anchor + dominant-baseline)。居中对齐需配合 <text> 的 text-anchor="middle" 和 tspan 的 dx 或统一 x 值。
下面是一个三行、整体水平居中、行间间距 1.2em 的例子:
<text x="100" y="60" text-anchor="middle" font-family="sans-serif" font-size="14"> <tspan x="100" dy="0em">第一行</tspan> <tspan x="100" dy="1.2em">第二行</tspan> <tspan x="100" dy="1.2em">第三行</tspan> </text>
-
x="100"定义了所有<tspan>的水平基准点(因为text-anchor="middle",所以文字以 x=100 为中点) - 首行
dy="0em"表示从<text>的y="60"开始;后续每行叠加dy - 若想首行也向下偏移(比如让第一行视觉上更居中),可设
dy="-0.6em"起始,再逐行 +1.2em
text-anchor 和 dominant-baseline 的组合效果
水平对齐靠 text-anchor(start/middle/end),垂直对齐靠 dominant-baseline(alphabetic/middle/hanging 等)。但注意:dominant-baseline 作用于整个 <text>,不是每个 <tspan>;而 dy 是相对于前一个 <tspan> 的基线偏移。
- 默认
dominant-baseline="alphabetic",此时y指向字母基线,不是文字框中心 - 设
dominant-baseline="middle"可让y更接近视觉垂直中心,但需配合字体度量调整 - 实际项目中,用
dy控制行距比依赖dominant-baseline更可靠
动态生成多行 <tspan> 时的常见坑
用 JavaScript 拼接或 React 渲染时,容易忽略单位、继承和坐标重置问题。
- 省略
dy单位(如写dy="1.2")在部分浏览器中可能失效,必须写dy="1.2em"或dy="16"(像素) -
<tspan>不继承父<text>的text-anchor,需显式设置或依赖父级继承(多数浏览器会继承,但不保证) - 若用
transform缩放整个<text>,dy值也会被缩放——建议用scale()包裹外层<g>,而非直接作用于<text> - 中文/emoji 混排时,
em行高可能不均,可改用固定像素值如dy="20"更可控
换行和对齐真正麻烦的不是语法,而是基线、度量、字体渲染差异这三层叠加——测一种字体行得通,换一种就偏几像素,这是 SVG 文本最常被低估的复杂点。










