SVG テキスト
text / tspan / textPath。フォント、整列、文字単位の装飾、パスに沿わせる、フィットする方法まで。
text 要素
<text x="50" y="50" font-family="sans-serif" font-size="20">
Hello SVG
</text>
- x / y — 文字のベースライン位置(左下基準)
- HTML と違って枠が無い(文字数で広がる)
- 選択・コピーも可(本物のテキスト)
主要な属性
| 属性 | 意味 |
|---|---|
| font-family | フォント |
| font-size | サイズ |
| font-weight | 太さ |
| font-style | italic 等 |
| text-anchor | start / middle / end(横方向の整列) |
| dominant-baseline | middle / hanging / alphabetic(縦方向) |
| letter-spacing | 字間 |
| word-spacing | 語間 |
| fill | 文字色 |
| stroke | 輪郭 |
| writing-mode | vertical-rl / horizontal-tb |
横方向の整列(text-anchor)
text-anchor:
start Hello ← x が左端
middle Hello ← x が中心
end Hello ← x が右端
<text x="100" y="50" text-anchor="middle" font-size="20">
Centered
</text>
縦方向の整列(dominant-baseline)
- auto / alphabetic(既定)— ベースライン
- middle — 中央揃え(数字に最適)
- hanging — 上から(東アジア用途)
- central — 文字の中央
- ideographic — 縦書き用
tspan(部分装飾 / 改行)
<text x="50" y="50" font-size="16">
Hello
<tspan fill="orange" font-weight="bold">SVG</tspan>
World
</text>
tspan で改行
SVG 1 は自動折り返しなし。tspan + x + dy で手動改行:
<text x="0" y="20">
<tspan x="0" dy="0">1 行目</tspan>
<tspan x="0" dy="1.2em">2 行目</tspan>
<tspan x="0" dy="1.2em">3 行目</tspan>
</text>
個別の x / y
<!-- 文字ごとに位置指定(タイポグラフィ表現) -->
<text>
<tspan x="10" y="20">H</tspan>
<tspan x="30" y="40">i</tspan>
</text>
textPath(パスに沿った文字)
<defs>
<path id="curve" d="M 10 80 Q 100 10 190 80" fill="none" />
</defs>
<text font-size="16">
<textPath href="#curve">
曲線に沿った文字列
</textPath>
</text>
属性
- startOffset: 開始位置(% or 絶対値)
- side:
left/right(パスのどちら側) - method:
align(既定)/stretch
SVG 2 の x="..." のリスト
text や tspan に複数の x を渡すと各文字に適用される(Animated typography で多用):
<text x="10 20 30 40 50" y="50">Hello</text>
<!-- H=10, e=20, l=30, l=40, o=50 -->
Web フォント
<style>
@import url("https://fonts.googleapis.com/css2?family=Inter&display=swap");
text { font-family: Inter, system-ui, sans-serif; }
</style>
外部 SVG ファイルではフォントがロードされないことがある(→ ファイルに埋め込むか、ブラウザフォントに頼る)。
テキスト → パス化
ロゴでフォントを誰の環境でも同じに見せたいなら、Illustrator / Inkscape でパスにアウトライン化。 編集はできなくなるが、フォント環境に依存しない。
整列を厳密に(dominant-baseline と組合せ)
<circle cx="50" cy="50" r="40" />
<text x="50" y="50"
text-anchor="middle"
dominant-baseline="central"
font-size="20">
Hi
</text>
円の真ん中に文字を置く定番セット。
foreignObject(HTML 埋め込み)
SVG の中にHTML を直接埋め込める。複雑なレイアウト / 改行付きテキストで便利。
<foreignObject x="10" y="10" width="200" height="100">
<div xmlns="http://www.w3.org/1999/xhtml" style="font-size: 14px">
HTML が入る。
自動的に折り返す段落も普通に書ける。
</div>
</foreignObject>
注意
- SVG ファイルとして配信したとき非対応ブラウザがある(Safari の SVG ファイル直開きなど)
- 選択 / コピーは普通の HTML として動く
- レンダリングコストはやや高い
テキストの長さを揃える
<text x="10" y="20" textLength="180" lengthAdjust="spacingAndGlyphs">
Stretched to 180
</text>
- textLength: 全体長を強制
- lengthAdjust:
spacing(字間のみ)/spacingAndGlyphs(文字も伸縮)
writing-mode(縦書き)
<text writing-mode="vertical-rl" font-size="20">縦書きテキスト</text>
CSS で変える
svg text { font-family: 'Inter', sans-serif; }
svg .heading { font-size: 32px; font-weight: 700; }
テキストの上にエフェクト
フチ
<text stroke="black" stroke-width="3" paint-order="stroke" fill="white">
Outlined
</text>
paint-order を stroke にすると、線が下、塗りが上で重なる。
影
<text style="filter: drop-shadow(2px 2px 2px rgba(0,0,0,.3))">
Shadow
</text>
グラデ文字
<defs>
<linearGradient id="g" x2="100%">
<stop offset="0%" stop-color="orange" />
<stop offset="100%" stop-color="purple" />
</linearGradient>
</defs>
<text fill="url(#g)" font-size="48">Gradient</text>
失敗パターン
| 症状 | 対処 |
|---|---|
| 自動改行されない | SVG 1 の仕様。tspan で手動 / foreignObject |
| 整列がずれる | text-anchor + dominant-baseline をセットで |
| 外部 SVG でフォントが違う | システムフォント / アウトライン化 |
| テキストパスがズレる | startOffset / 文字数とパス長 |
| 選択できない | pointer-events / user-select 設定 |
テキスト派 vs パス派
編集 / 翻訳 / 検索が要るならテキストのまま。同じ見た目を保証したいならパス化。 多言語対応の SVG はテキスト派でないと辛い。