はじめに
今回は、viewBoxについてまとめたいと思います。
viewBoxはよくわからず、どういう動作なのか理解できていませんでしたが、色々と調べようやくわかってきたような気がしますので、それを整理していきたいと思います。
最初は、viewBoxの配下の要素にソースを書いていくため、viewBoxの範囲内に描画していくものと思っていましたが、それは誤りで、どちらかというと、描画したところから、viewBoxで特定の箇所を切り取るってことなんですよね。
今もしっくりこないところはあるのですが、整理していきたいと思います。
今回実施する内容
viewBoxは内容が色々ありますので、まずは基本的な部分をまとめたいと思います。
今回は、viewBoxとviewportの縦横比が同じ場合についてまとめたいと思います。
ソースコード(Git Hub)
環境
OS: Windows 11 JP (64bit)
Edge: バージョン 142.0.3595.53 (公式ビルド) (64 ビット)
参考
7 Coordinate Systems, Transformations and Units
用語
キャンバスとviewBoxとviewport
SVGのviewBox属性は、とても重要な属性です。これがわからないと少しの変更で、意図しないSVG画像になったりします。
よりよく理解するために、概念から整理します。まずはイメージを図示します。

- 左側が「キャンバス」と呼ばれる「仮想の表示領域」。ここに描画したい内容を記載する。
- 右側が実際のブラウザなどの画面。
- SVGは、「キャンバス」に描画して、
viewBoxで描画したい内容を切り取って、Edgeなどのブラウザ上に「実際の表示領域」にスケーリングして表示。 -
viewBoxは、「キャンバス」上の切り抜きたい(「実際の表示領域」に表示したい)場所を囲った矩形の領域。 -
viewportは、「実際の表示領域」の矩形。
したがって、上図では、「キャンバス」上に、「Build Mount」と描画しましたが、viewBoxで「Build Mo」までを囲っており、その結果、viewport( 「実際の表示領域」の矩形)では、「Build Mo」だけが表示されます。
SVGがとても難しいと思うのは、viewBoxの設定だったり、viewBoxとviewportの矩形の形(縦横比)が違ったりして、思ったようにブラウザに表示されないところかなと思います。
まずはこの基本をしっかりおさえて、慣れていく必要があると思います。
といってもまだ慣れないのですけれど。
viewBoxの設定
viewBox属性のフォーマットは以下です。
viewBox="min-x, min-y, width, height"
-
min-x:「キャンバス」上のviewBoxの矩形の左上のX軸の値。 -
min-y:「キャンバス」上のviewBoxの矩形の左上のY軸の値。 -
width:「キャンバス」上のviewBoxの矩形の横幅。 -
height:「キャンバス」上のviewBoxの矩形の縦幅。
特徴としては、ここには単位はないということです。
「キャンバス」上で記載するときの座標や幅などの値は単位はなく相対的なものであって、viewBoxをviewportに割り当てるときに具体的な単位となります。
viewportの設定
viewportは属性ではありませんが、設定はwidthやheightで設定します。
<svg width="width" height="height">
</svg>
viewBoxサンプル
ここからは、viewBoxを使ったサンプルを紹介します。
1. viewBox="0 0 300 200" width="300px" height="300px"
<svg class="border" viewBox="0 0 300 200" width="300px" height="200px">
<circle cx="150" cy="100" r="50" fill="red" />
</svg>
viewBoxとviewportのwidth、heightを設定します。
このときに、viewBoxのwidthとheightと、viewportのwidthとheightの数値は同じにします。
これが一番基本的でわかりやすいと思います。
viewBoxのmin-xとmin-yはそれぞれ0に設定します。これも最もシンプルでわかりやすいと思います。
class属性は、このSVG画像の枠を線で囲うためのCSSで、別途定義しています。viewBox自体には関係ありません。
<circle>では中心位置をcx="150" cy="100"で半径r="50"で赤色の円を記載します。
2. viewBox="100 50 300 200" width="300px" height="300px"
<svg class="border" viewBox="100 50 300 200" width="300px" height="200px">
<circle cx="150" cy="100" r="50" fill="red" />
</svg>
1の例から、viewBoxのmin-xを0⇒100、min-yを0から50に変更しました。
「キャンバス」上のviewBoxをずらして、赤色の円がギリギリ入るようにしました。
3. viewBox="150 100 300 200" width="300px" height="200px"
1の例から、viewBoxのmin-xを0⇒150、min-yを0から100に変更しました。
「キャンバス」上のviewBoxをずらして、赤色の円の1/4部分が表示されるようにしました。
もともと円を描いていたはずなのに、1/4円になります。
こういう動作が理解が難しいですよね。
4. viewBox="0 0 600 400" width="300px" height="300px"
<svg class="border" viewBox="0 0 600 400" width="300px" height="200px">
<circle cx="300" cy="150" r="100" fill="red" />
</svg>
1の例から、viewBoxのwidthを300⇒600、heightを200⇒400に変更しました。
また、<circle>もサイズを変更し、位置も調整しました。
<circle cx="150" cy="100" r="50" fill="red" />
↓
<circle cx="300" cy="150" r="100" fill="red" />
viewportの実際の表示領域は、1の例と同じです。
「キャンバス」上のwidthとheightのサイズを大きくすることで、「キャンバス」上の解像度が上がったということです。今回はシンプルな円だけですので、実際の表示領域の見た目は1の例と全く同じです。
解像度を上げるということはそれだけ細かい描写ができるようになるということなので、どのくらいがよいのかは作成者次第とは思いますが、大きな値を設定しておいてもファイルサイズが極端に大きくなるわけではないため、余裕をもった大きさでもかまわないのかなと思います。
viewBoxとviewportの設定なし時の動作
viewBoxもviewportは任意であるため、設定しないこともできます。
そうした場合にどうなるかを示します。
viewBox |
viewportのwidithとheight
|
viewBoxの動作 |
viewportの動作` |
|---|---|---|---|
| なし | なし |
viewportに従う。viewBox="0 0 300 150"相当。 |
デフォルトのwidth="300px" height="150px"
|
| なし | あり |
viewportに従う。 |
設定値通り。 |
| あり | なし | 設定値通り。 |
widthはブラウザの横幅。heightはviewBoxの縦横比に従う。 |
| あり | あり | 設定値通り。 | 設定値通り。縦横比の動作はpreserveAspectRatio属性に従う。 |
5. viewBoxなし、viewportなし
<svg class="border">
<circle cx="150" cy="100" r="50" fill="red" />
</svg>
viewBoxはviewportの値を持ってくるようになるため、viewBox="0 0 300 150"相当になります。
viewportはデフォルトのwidth="300px" height="150px"になります。
6. viewBoxなし、viewportあり
<svg class="border" width="300" height="200">
<circle cx="150" cy="100" r="50" fill="red" />
</svg>
viewBoxは、viewportの値を持ってくるようになるため、この例ではviewBox="0 0 300 200"相当になります。
viewportは設定した通りです。
7. viewBoxあり、viewportなし
<svg class="border" viewBox="0 0 300 200">
<circle cx="150" cy="100" r="50" fill="red" />
</svg>
viewBoxは設定した通りです。
viewportはwidthはブラウザの横幅になり、heightは、viewBoxで設定した縦横比に応じて設定されます。
8. viewBoxあり、viewportあり
<svg class="border" viewBox="0 0 300 200" width="300px" height="100px">
<circle cx="150" cy="100" r="50" fill="red" />
</svg>
viewBoxは設定した通りであり、viewportも設定した通りです。
しかし、この例では、あえてviewBoxとviewportの縦横比を変更しており、縦横比がほかの例と違っていびつに見えるかと思います。
この辺の動作は、次回縦横比の比率が違う場合で取り上げたいと思います。
おわりに
今回はviewBox、viewportがどういったものか、および、その基本的な使い方とサンプルを示しました。
この辺は基本なところでありつつも、難解で、期待しない画像が出来上がることが何回もありました。
なかなか難しいですよね。
また、viewBoxやviewportは、なるべく設定したほうがよさそうだなと思いました。








