SVGはviewBoxで内部座標系を決め、preserveAspectRatioで表示領域への収め方を指定する
公開日: 執筆:佐藤
SVGの大きさを調整するときは、表示領域と内部座標系を分けます。widthとheightは表示領域の大きさを決め、viewBoxは図形を描く内部座標系の範囲を決めます。
表示領域とviewBoxの縦横比が違う場合は、preserveAspectRatioで全体を収めるか、領域を覆うか、縦横を別々に伸縮するかを指定します。この役割を分けると、余白、切取り、変形を意図して選べます。
viewBoxは四つの数値で内部座標系を決める
viewBoxには、min-x、min-y、width、heightの四つの数値を空白またはコンマで区切って指定します。
<svg width="300" height="300" viewBox="0 0 200 100">
<!-- 図形 -->
</svg>
この仮例では、表示領域は幅300、高さ300です。内部座標系は、左上の0 0から幅200、高さ100の範囲です。viewBoxの縦横比は2対1、表示領域は1対1なので、そのままでは縦横比が一致しません。
viewBoxを単なる表示幅と考えると、widthやheightとの違いが分からなくなります。viewBoxは、内部のどの範囲を、表示領域へ写すかを指定するものです。
preserveAspectRatioは縦横比と位置を指定する
preserveAspectRatioは、viewBoxがある要素で、内部座標系を表示領域へどのように対応させるかを決めます。
preserveAspectRatio="xMidYMid meet"
xMidYMidは、x方向とy方向の中央を合わせます。meetは縦横比を保ち、viewBox全体が表示領域へ入る倍率を選びます。preserveAspectRatioを省略した場合の初期値もxMidYMid meetです。
位置は、x方向のMin、Mid、Maxと、y方向のMin、Mid、Maxを組み合わせて指定できます。たとえばxMinYMinなら、表示領域の左上とviewBoxの左上を合わせます。
meet、slice、noneは余白、切取り、変形を分ける
先ほどの幅300、高さ300の表示領域へ、幅200、高さ100のviewBoxを写す場合を比べます。
| 指定 | 縦横比 | 表示結果 |
|---|---|---|
xMidYMid meet |
保つ | 図形全体を幅300、高さ150に収め、上下に余白を残す |
xMidYMid slice |
保つ | 図形を幅600、高さ300まで拡大し、左右の一部を表示領域の外へ出す |
none |
保たない | 幅と高さを別々の倍率で300四方へ合わせ、図形を縦方向へ引き伸ばす |
meetは、図形全体を欠けずに見せたい場合に使います。表示領域と縦横比が違えば、どこかに余白ができます。
sliceは、表示領域を余白なく覆いたい場合に使います。縦横比を保つため、図形の一部が表示領域の外へ出ます。どの部分を残すかは、xMinYMinなどの位置指定で変わります。
noneは、表示領域へ縦横を別々に合わせます。余白も切取りも避けられますが、円が楕円になるように図形の形が変わります。
同じSVGで三つの収め方を試す
次は、幅200、高さ100の内部座標系に円を描き、300四方の表示領域へ収める説明用の例です。
<svg
width="300"
height="300"
viewBox="0 0 200 100"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="0" y="0" width="200" height="100" fill="#e7eef5"></rect>
<circle cx="100" cy="50" r="35" fill="#2f5f83"></circle>
</svg>
まずmeetで図形全体と余白を確認します。次にmeetをsliceへ変え、左右が表示領域の外へ出ることを確かめます。最後に値全体をnoneへ変え、円が楕円へ変形することを確認します。
preserveAspectRatioは、viewBoxを指定していない要素では、表示結果に作用しません。収め方が変わらない場合は、値の綴りだけでなく、対象要素にviewBoxがあるかを先に確認します。
表示領域の変更と図形の編集を分ける
SVGを小さく表示したいだけなら、内部のpathやcircleの座標をすべて書き換える必要はありません。図形の座標はviewBoxの内部座標系に置き、表示側のwidthとheightを変更します。
一方、図形の外周に不要な空きがある場合は、表示領域だけでなくviewBoxの範囲を確認します。viewBoxを狭めれば、内部座標系のうち表示する範囲が変わります。図形自体を編集したのか、見せる範囲を変えたのかを区別してください。
最初の一手は、SVGについて、表示したい幅と高さ、図形が使う最小x、最小y、幅、高さを書き出すことです。その二つの縦横比が違うなら、全体表示、全面表示、変形許容のどれを優先するか決めてからpreserveAspectRatioを選びます。
関連記事

