• SVGはviewBoxで内部座標系を決め、preserveAspectRatioで表示領域への収め方を指定する

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を選びます。

戻る