【SVG】svgのviewBox属性。図解!余白ができる場合どうなる?

前の記事でsvgのviewBoxの基本パターンを5つ見ました。基本パターン以外に少しイレギュラーなケースがあるので、今回はそちらを図解していきます。

目次(SVGについて複数ページ書いてます)

検証で使用するsvg(幅200px、高さ200px)※他の検証と同じsvgです

svgの他ページと同じ検証用svgの説明です。不要な方は読み飛ばしてくださいm(__)m

検証用に下記のような図形を使用します。
どの部分が抜き出されているか、拡大・縮小はどうなっているか、見た感じで分かりやすいように考えました。下記をご覧ください。一通り説明します。

  • SVGの幅・高さはともに200px
  • 4色の正方形。サイズは全て同じで幅100×高さ100
  • 左上に赤色の正方形(座標は x=0, y=0)
  • 右上に青色の正方形(座標は x=100, y=0)
  • 左下に黄色の正方形(座標は x=0, y=100)
  • 右下に黒色の正方形(座標は x=100, y=100)
  • 白い縦線・横線を10間隔で格子状の白い縦線・横線(各19本)

svgソースを見る[クリックすると開きます]

<svg class="square" width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <!-- 正方形 -->
 <rect x="0" y="0" width="100" height="100" fill="red" />
 <rect x="100" y="0" width="100" height="100" fill="blue" />
 <rect x="0" y="100" width="100" height="100" fill="yellow" />
 <rect x="100" y="100" width="100" height="100" fill="black" />
 <!-- 線(グリッド) --> 
 <line x1="0" y1="10" x2="200" y2="10" stroke="white" />
 <line x1="0" y1="20" x2="200" y2="20" stroke="white" />
 <line x1="0" y1="30" x2="200" y2="30" stroke="white" />
 <line x1="0" y1="40" x2="200" y2="40" stroke="white" />
 <line x1="0" y1="50" x2="200" y2="50" stroke="white" />
 <line x1="0" y1="60" x2="200" y2="60" stroke="white" />
 <line x1="0" y1="70" x2="200" y2="70" stroke="white" />
 <line x1="0" y1="80" x2="200" y2="80" stroke="white" />
 <line x1="0" y1="90" x2="200" y2="90" stroke="white" />
 <line x1="0" y1="100" x2="200" y2="100" stroke="white" />
 <line x1="0" y1="110" x2="200" y2="110" stroke="white" />
 <line x1="0" y1="120" x2="200" y2="120" stroke="white" />
 <line x1="0" y1="130" x2="200" y2="130" stroke="white" />
 <line x1="0" y1="140" x2="200" y2="140" stroke="white" />
 <line x1="0" y1="150" x2="200" y2="150" stroke="white" />
 <line x1="0" y1="160" x2="200" y2="160" stroke="white" />
 <line x1="0" y1="170" x2="200" y2="170" stroke="white" />
 <line x1="0" y1="180" x2="200" y2="180" stroke="white" />
 <line x1="0" y1="190" x2="200" y2="190" stroke="white" />
 <line x1="10" y1="0" x2="10" y2="200" stroke="white" />
 <line x1="20" y1="0" x2="20" y2="200" stroke="white" />
 <line x1="30" y1="0" x2="30" y2="200" stroke="white" />
 <line x1="40" y1="0" x2="40" y2="200" stroke="white" />
 <line x1="50" y1="0" x2="50" y2="200" stroke="white" />
 <line x1="60" y1="0" x2="60" y2="200" stroke="white" />
 <line x1="70" y1="0" x2="70" y2="200" stroke="white" />
 <line x1="80" y1="0" x2="80" y2="200" stroke="white" />
 <line x1="90" y1="0" x2="90" y2="200" stroke="white" />
 <line x1="100" y1="0" x2="100" y2="200" stroke="white" />
 <line x1="110" y1="0" x2="110" y2="200" stroke="white" />
 <line x1="120" y1="0" x2="120" y2="200" stroke="white" />
 <line x1="130" y1="0" x2="130" y2="200" stroke="white" />
 <line x1="140" y1="0" x2="140" y2="200" stroke="white" />
 <line x1="150" y1="0" x2="150" y2="200" stroke="white" />
 <line x1="160" y1="0" x2="160" y2="200" stroke="white" />
 <line x1="170" y1="0" x2="170" y2="200" stroke="white" />
 <line x1="180" y1="0" x2="180" y2="200" stroke="white" />
 <line x1="190" y1="0" x2="190" y2="200" stroke="white" />
</svg>

3.viewBoxを検証

viewBoxの設定の仕方と意味を見ておきます。viewBox=”x y width height”と設定しますが、区切りは半角スペースでも半角カンマでもどちらでも良いようです。本記事では半角スペースで書きます。各値、そのままの意味ですが、一つずつ見ておきましょう。

  • x・・・左上の x座標
  • y・・・左上の y座標
  • width・・・幅
  • height・・・高さ

検証:予想と違う?

今回、検証に使用するviewBoxは「viewBox=”-100 -100 400 200″」になります。私の予想した図とは異なったので、取り上げました。(予想どおりの方もいるかと思います、その方は読み飛ばしてくださいm(__)m)
※このviewBoxは次のページで検証するパターンです

透けたオレンジの部分がviewBoxの範囲

まず、viewBoxの範囲が分かるよう上の画像を作成しましたので、ご覧ください。こちらを見ると、黄、黒の正方形はviewBoxの範囲外なので、表示されないように感じます。
それでは、実際にどのような図になるのでしょう。「viewBox=”-100 -100 400 200″」を設定したsvgを下記に用意しましたので、見てみてください。

引用:Firefoxの要素の検証

私の予想とは違い黄・黒の正方形も表示されました

どういった理由でこのようになるのでしょう?

図解!svgの余白はどうなる?

viewBoxの設定値からsvgに表示するまでの流れを見てみましょう。主に見る点はsvg領域に余白が出来たとき、何が表示されるか?です。あわせて、余白がある場合に中央配置になる理由についても少し触れます。

viewBoxの範囲

①viewBoxで指定された範囲は上の画像のとおりです。
viewBoxの幅は400px、高さは200pxです。

viewBoxの範囲を抜き出した図形

②実際に図を抜き出します。
幅は400px、高さは200pxです。中央下に図(赤と青の正方形)がくる形で抜き取られます。

viewBoxで抜き出した図形をsvgに入れたい

③viewBoxで抜き出した図形をsvgにどのようにはめこむか考えます

図の拡大・縮小について

svgの属性に「preserveAspectRatio」があります。この属性の初期値は「xMidYMid meet」です。これは「xMidYMid」と「meet」の2つが設定されているということです。この内「meet」の方が拡大・縮小に関連します。「meet」とは幅と高さを大きい方に合わせる、つまりviewboxはsvg領域内に収まるように拡大・縮小します

高さを合わせた場合、はみ出る

④viewBoxとsvg領域の高さを合わせてみます。どちらの高さも200pxなのでviewBoxで抜き出した図をそのままのサイズでsvgに入れてみます。
svgの左右から100pxはみ出して、収まりませんでした。

幅を合わせた場合、きれいに入る

⑤viewBoxとsvg領域の幅を合わせてみます。viewBoxの幅は400px、svg領域の幅は200pxなのでviewBoxで指定した図を半分(1/2)に縮小して入れましょう。viewBoxで抜き出した図は幅200px、高さ100pxになります。
svgの領域にきれいに収まりました

はめこんだviewBoxの図の上下に余白がある

⑥viewBoxはきれいにはまりましたが、余白の扱いがどうなるかが残っています。

図が縦横ともに中央配置される理由

svgの属性に「preserveAspectRatio」があります。この属性の初期値は「xMidYMid meet」です。これは「xMidYMid」と「meet」の2つが設定されているということです。この内「xMidYMid」の方が表示位置に関連します。「xMidYMid」とはviewBoxの中間点のX値とsvg領域の中間点のX値を揃える、および、viewBoxの中間点のY値とviewportの中間点のY値を揃えるというものです。つまり、縦横ともに中央に配置するということです。

余白にはviewBoxには指定されていない部分もsvg領域に収まる部分は表示される

⑦svg領域の余白にはviewBoxでは指定されていない部分の図も表示されます

ただし、黄・黒の正方形部分はviewBoxとしては認識されていないので、拡大・縮小には関係ありません。上記のとおりviewBoxで決まった通り1/2の大きさに縮小されます。

これらが余白に図が表示される流れになります。拡大・縮小・配置には影響を与えないが、余白があればviewBoxの範囲外でも図は表示されるということが分かりました。私の予測には反しましたが、納得はできました。

svgの「viewBox」の様々なパターン21件を検証

次はsvgの「viewBox」の組み合わせを21パターン検証しました。