LoginSignup
29
32

More than 1 year has passed since last update.

SVGの描画領域

Last updated at Posted at 2019-09-08

ビューポート

図形を描画する領域のサイズです。
一番外側のsvgタグのwidth、heightで指定します。
(svgタグにposition:absoluteやposition:fixedが指定されていればpositionが優先されます)

ビューポートの単位

長さの単位は em, ex, px, pt, pc, cm, mm, in, %を利用できます。
単位を省略した場合はpxになります。

ビューボックス

viewBox属性

SVGの描画領域の定義に使います。
viewBoxで指定できる値は4つです。
viewBox="x, y, width, height"(カンマか、半角スペースで区切る)

内容
x 左からのx座標の位置
y 上からのy座標の位置
width ビューポートの幅
height ビューポートの高さ

ビューポートとビューボックス

特別に理由が無ければビューポートとビューボックスのwidth, heightは揃えておいた方が扱いやすいです。
svgタグにwidth,height属性を指定せずviewBox属性のみを指定した場合、viewBoxのwidthとheightを、ビューポートのwidth、heightとして扱います。

svg
<svg width="400" height="400" viewBox="0, 0, 400, 400" xmlns="http://www.w3.org/2000/svg">
  <circle cx="50" cy="50" r="50" fill="blue" />
</svg>

preserveAspectRatio

preserveAspectRatio属性

svg
preserveAspectRatio="align [meet|slice]"

svgタグには、何も指定しなくてもデフォルトで、preserveAspectRatio="xMidYMid meet"が指定されています。

preserveAspectRatioの値

内容
xMinYMin 要素のviewBoxのxとviewportの最小のX値を揃える
要素のviewBoxのyとviewportの最小のY値を揃える
xMidYMin 要素のviewBoxの中間点のX値とviewportの中間点のX値を揃える
要素のviewBoxのyとviewportの最小のY値を揃える
xMaxYMin 要素のviewBoxのx+widthとviewportの最大のX値を揃える
要素のviewBoxのyとviewportの最小のY値を揃える
xMinYMid 要素のviewBoxのxとviewportの最小のX値を揃える
要素のviewBoxの中間点のY値とviewportの中間点のY値を揃える
xMidYMid(デフォルト) 要素のviewBoxの中間点のX値とviewportの中間点のX値を揃える
要素のviewBoxの中間点のY値とviewportの中間点のY値を揃える
xMaxYMid 要素のviewBoxのx+widthとviewportの最大のX値を揃える
要素のviewBoxの中間点のY値とviewportの中間点のY値を揃える
xMinYMax 要素のviewBoxのxとviewportの最小のX値を揃える
要素のviewBoxのy+heightとviewportの最大のY値を揃える
xMidYMax 要素のviewBoxの中間点のX値とviewportの中間点のX値を揃える
要素のviewBoxのy+heightとviewportの最大のY値を揃える
xMaxYMax 要素のviewBoxのx+widthとviewportの最大のX値を揃える
要素のviewBoxのy+heightとviewportの最大のY値を揃える
none 不均等にスケーリングし、ビューボックスをビューポートの四角形に一致させる
オプションは無視される

preserveAspectRatioのオプション

内容
meet(デフォルト) ビューポートとビューボックスの幅と高さを大きい方に合わせる(viewboxはviewport内に収まる)
slice ビューポートとビューボックスの幅と高さの小さい方に合わせる(viewboxがviewportからはみ出す場合がある)

描画範囲の設定例

サンプル画像について

  • 2つの円は半径50、中心点はそれぞれ(0,0)、(400,200)
  • オレンジの四角はviewBoxのwidth、heightの指定と同じの幅と高さ

ビューポートとビューボックスの幅と高さが同じ場合

width height
ビューポート 400 200
ビューボックス 400 200

ビューポートとビューボックスの幅と高さが同じなのでビューボックスの範囲がビューポートと一致します。
ビューポートの左上と右下を中心にした円が1/4だけ描画されています。
01.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 200">
  <rect x="0" y="0" width="400" height="200" fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

左上の円が完全に描画されるように、viewBoxの中心点を-50,-50に指定(円の半径が50pxのため)すると左上の円は全体が表示されましたが、右下の円は範囲外になり表示されなくなりました。

02.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="-50 -50 400 200">
  <rect x="-50" y="-50" width="400" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

ビューポートとビューボックスの数値は異なるが縦横比が同じ場合

ビューボックスの幅と高さがビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 800 400

ビューポートとビューボックスのサイズが等しい場合の4倍が描画範囲になります。

03.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 400">
  <rect x="0" y="0" width="800" height="400"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

ビューボックスの幅と高さがビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 200 100

ビューポートとビューボックスのサイズが等しい場合の1/4が描画範囲になります。(大きさは4倍)

04.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 200 100">
  <rect x="0" y="0" width="200" height="100"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

ビューポートとビューボックスの縦横比が違う場合

viewportとviewboxの縦横比が一致していない場合、preserveAspectRatio属性が影響してきます。
初期値は"xMidYMid meet"です。

preserveAspectRatio="xMidYMid meet"でビューボックスの幅がビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 800 100

ビューボックスの幅が倍なので高さの割合が半分になり、xMidYMidの影響で中央寄せされています。

05.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 200" preserveAspectRatio="xMidYMid meet">
  <rect x="0" y="0" width="800" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMidYMid meet"でビューボックスの高さがビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 400 400

ビューボックスの高さが倍なので幅の割合が半分になり、xMidYMidの影響で中央寄せされています。

06.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 400" preserveAspectRatio="xMidYMid meet">
  <rect x="0" y="0" width="400" height="400"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMidYMid meet"でビューボックスの幅がビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 200 100

ビューボックスの幅が半分になり、xMidYMidの影響で中央寄せされています。(大きさは2倍)

07.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet">
  <rect x="0" y="0" width="200" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMidYMid meet"でビューボックスの高さがビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 400 100

ビューボックスの高さの割合が半分になり、xMidYMidの影響で中央寄せされています。(大きさは2倍)

08.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 100" preserveAspectRatio="xMidYMid meet">
  <rect x="0" y="0" width="400" height="100"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="none"でビューボックスの幅がビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 800 200

ビューポートの縦横比に合わせるために高さが2倍に引き伸ばされるので、図形が縦に伸びています。(縦だけ2倍)

09.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 200" preserveAspectRatio="none">
  <rect x="0" y="0" width="800" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="none"でビューボックスの高さがビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 400 400

ビューポートの縦横比に合わせるために幅が2倍に引き伸ばされるので、図形が横に伸びています。(横だけ2倍)

10.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 400" preserveAspectRatio="none">
  <rect x="0" y="0" width="400" height="400"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="none"でビューボックスの幅がビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 200 200

ビューポートの縦横比に合わせるために幅が2倍に引き伸ばされるので、図形が横に伸びています。(縦2倍、横4倍)

11.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="none">
  <rect x="0" y="0" width="200" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="none"でビューボックスがビューポートの半分の場合(高さだけ)

width height
ビューポート 400 200
ビューボックス 400 100

ビューポートの縦横比に合わせるために、高さが2倍に引き伸ばされるので、図形が縦に伸びています。(縦4倍、横2倍)

12.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 100" preserveAspectRatio="none">
  <rect x="0" y="0" width="400" height="100"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMinYMin meet"でビューボックスの幅がビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 800 200

ビューボックスの幅が倍なので高さの割合が半分になり、xMinYMinの影響で上寄せされています。

13.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 200" preserveAspectRatio="xMinYMin">
  <rect x="0" y="0" width="800" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMinYMin meet"でビューボックスの高さがビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 400 400

ビューボックスの高さが倍なので幅の割合が半分になり、xMinYMinの影響で左寄せされています。

14.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin">
  <rect x="0" y="0" width="400" height="400"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMinYMin meet"でビューボックスの幅がビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 200 200

ビューボックスの幅の割合が半分になり、xMinYMinの影響で左寄せされています。(大きさは2倍)

15.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin">
  <rect x="0" y="0" width="200" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMinYMin meet"でビューボックスの高さがビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 400 100

ビューボックスの高さの割合が半分になり、xMinYMinの影響で上寄せされています。(大きさは2倍)

16.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 100" preserveAspectRatio="xMinYMin">
  <rect x="0" y="0" width="400" height="100"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMaxYMax meet"でビューボックスの幅がビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 800 200

ビューボックスの幅が倍なので高さの割合が半分になり、xMinYMinの影響で下寄せされています。

17.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 200" preserveAspectRatio="xMaxYMax">
  <rect x="0" y="0" width="800" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMaxYMax meet"でビューボックスの高さがビューポートの倍の場合

width height
ビューポート 400 200
ビューボックス 400 400

ビューボックスの高さが倍なので幅の割合が半分になり、xMinYMinの影響で右寄せされています。

18.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 400" preserveAspectRatio="xMaxYMax">
  <rect x="0" y="0" width="400" height="400"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMaxYMax meet"でビューボックスの幅がビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 200 100

ビューボックスの幅の割合が半分になり、xMinYMinの影響で下寄せされています。(大きさは2倍)

19.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMaxYMax">
  <rect x="0" y="0" width="200" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatio="xMaxYMax meet"でビューボックスの高さがビューポートの半分の場合

width height
ビューポート 400 200
ビューボックス 400 100

ビューボックスの高さの割合が半分になり、xMinYMinの影響で下寄せされています。(大きさは2倍)

20.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 100" preserveAspectRatio="xMaxYMax">
  <rect x="0" y="0" width="400" height="100"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

preserveAspectRatioのオプションのmeetとsliceの比較

width height
ビューポート 400 200
ビューボックス 800 200

meet(初期値)

preserveAspectRatio="xMidYMid meet"
縦横の大きい方がviewportいっぱいに表示されます。

21.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 200" preserveAspectRatio="xMidYMid meet">
  <rect x="0" y="0" width="800" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>

slice

preserveAspectRatio="xMidYMid slice"
縦横の小さい方がビューポートいっぱいに表示されるので大きい方ははみ出してしまいます。
これまでの例と異なり、オレンジの四角の左右の輪郭線が見えなくなっています。

22.png

svg
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 800 200" preserveAspectRatio="xMidYMid slice">
  <rect x="0" y="0" width="800" height="200"  fill="#e67e22" stroke="#EA2027" stroke-width="8px"/>
  <circle cx="0" cy="0" r="50" fill="#333"/>
  <circle cx="400" cy="200" r="50" fill="#888000"/>
</svg>
29
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
32