現場で役立つ、SVGアイコン調整術 第3回 SVGアイコンの余白の調整 - 2

SVG属性のpreserveAspectRatio属性による配置や、余白の切り取りについても紹介します。

発行

著者 藤田 智朗 フロントエンド・エンジニア
現場で役立つ、SVGアイコン調整術 シリーズの記事一覧

前回まで

前回はviewBoxの座標系と、viewBoxwidthheightの指定で、どのように表示領域と余白が決定されるのかを解説しました。

その際、widthheightの縦横比が異なる場合、たとえば、widthだけを2倍にした場合、また1/2にした場合には、表示領域が横2倍、横1/2倍になったりはしません。widthだけを2倍にした場合はアイコン自体の形大きさは変わらず余白が増え、widthだけを1/2にした場合はアイコンはアスペクト比を保持したまま縮小するという結果になることを確認しました。

この結果にはpreserveAspectRatio属性が関係しています。今回はこの属性について、掘り下げます。

SVGのpreserveAspectRatio属性

SVGのpreserveAspectRatio属性はその名の通り「アスペクト比(縦横比)を保持する」ためのものです。

preserveAspectRatio属性

preserveAspectRatio="xMidYMid meet"

これは2つの属性値から構成されています。

  • 1つ目のxMidYMidviewBoxと表示領域の配置を指定します。X軸とY軸の両方で中央揃え(Mid)することを意味します
  • 2つ目のmeetviewBoxを表示領域内に収めつつ、アスペクト比を保持します。内容全体が見えるように縮小されます

デフォルト値はpreserveAspectRatio="xMidYMid meet"となり、SVGコンテンツがwidthheightで指定された表示領域内で中央揃えされ、アスペクト比を保ったままこの表示領域内からはみ出さないように可能な限り大きく表示されます。

このデフォルト値であるxMidYMidmeetにより、アスペクト比が保持されたまま、余白が増えたり、アイコン部分が縮小される結果になりました。

1つ目の指定ではMidの他にMaxMinがあり、それぞれX軸とY軸方向で表示領域とviewBoxをどう配置するかを決定します。

たとえばxMinであればX軸はviewBoxと表示領域の最小値で揃える=左寄せということになります。

  • X軸(横)方向
    • xMin:X軸の最小位置(左寄せ)
    • xMid:X軸の中央位置(中央寄せ)
    • xMax:X軸の最大位置(右寄せ)
  • Y軸(縦)方向
    • YMin:Y軸の最小位置(上寄せ)
    • YMid:Y軸の中央位置(中央寄せ)
    • YMax:Y軸の最大位置(下寄せ)

*注:

xは小文字であるのに対して、Yは大文字である点に注意してください

これらを組み合わせて、たとえばxMinYMidなら「左寄せ・上下中央寄せ」、xMaxYMaxなら「右下寄せ」となります。

2つ目の指定にはmeetsliceがあります。

  • meetviewBox全体が表示領域からはみ出さないように表示されるようにスケーリングされる
  • slice:表示領域全体を埋めるようにスケーリングし、viewBoxのはみ出した部分は切り取られる

これはobject-fitbackground-sizecontaincoverと同じようなものだと考えても差し支えないでしょう。meetcontainと、slicecoverと同じような挙動になります。

また、2つ目を省略してpreserveAspectRatio="xMidYMid"のように書くことができます。この場合、2つ目のデフォルト値であるmeetが適用されます。

なお、アスペクト比を保持したくない場合はnoneを指定してpreserveAspectRatio="none"とすると、アスペクト比を無視して縦や横に引き伸ばされたアイコンになります。アスペクト比を保持しないで縦長や横長に引き伸ばしたい場合はnoneを指定します。

前回、preserveAspectRatioを何も指定しなかった際に、当初は、横または縦に引き伸ばされたアイコンになることを予想しました。しかし、デモで確認すると、そうはならないことを説明したのを覚えていますか?

その設定の鍵は、preserveAspectRatio属性にあるというところで、前回は終わってしまったのですが、実は、あのデモはpreserveAspectRatio属性にnoneを指定することで、この予想どおりの結果になります。

preserveAspectRatio属性による余白調整

このpreserveAspectRatioの特性をよく理解しておけば、SVGの余白をうまく調整できます。

viewBoxと表示領域のアスペクト比が異なる場合、preserveAspectRatioの配置指定により、自然に余白が生まれます。これを利用することで、意図的に余白を作ることができます。

preserveAspectRatioのmeetで余白を作る

例えば、縦24px、横48pxの横長の表示領域に配置する場合を考えてみましょう。preserveAspectRatioのX軸部分を変えて、それぞれ次のようにして確認してみます。

  • xMinYMid meet:左寄せ(右に余白)
  • xMidYMid meet:中央寄せ(左右に余白・デフォルト)
  • xMaxYMid meet:右寄せ(左に余白)

中央寄せのxMidYMid meetは前述したようにpreserveAspectRatioが未指定だった場合のデフォルト値になります。

preserveAspectRatioによる余白の調整

<!-- 左寄せ(右に余白) -->
<svg viewBox="0 0 24 24" width="48" height="24" class="icon"
preserveAspectRatio="xMinYMid meet">
  <path d="M9 5L15 12L9 19" />
</svg>

<!-- 中央配置(左右に余白・デフォルト) -->
<svg viewBox="0 0 24 24" width="48" height="24" class="icon"
preserveAspectRatio="xMidYMid meet">
  <path d="M9 5L15 12L9 19" />
</svg>

<!-- 右寄せ(左に余白) -->
<svg viewBox="0 0 24 24" width="48" height="24" class="icon"
preserveAspectRatio="xMaxYMid meet">
  <path d="M9 5L15 12L9 19" />
</svg>

この場合、アイコンのviewBoxのアスペクト比(1:1)と表示領域のアスペクト比(2:1)が異なりますが、meetによってviewBox全体が収まるように調整された結果、高さは同じであるためアイコンはもとの大きさのままとなり、左右のどちらか、または両方に余白が作られます。

上下の余白を調整したい場合は、heightYMid部分を調整します。

preserveAspectRatioによる余白の調整

<!-- 上寄せ(下に余白) -->
<svg viewBox="0 0 24 24" width="24" height="48" class="icon"
preserveAspectRatio="xMidYMin meet">
  <path d="M9 5L15 12L9 19" />
</svg>

<!-- 中央配置(上下に余白・デフォルト) -->
<svg viewBox="0 0 24 24" width="24" height="48" class="icon"
preserveAspectRatio="xMidYMid meet">
  <path d="M9 5L15 12L9 19" />
</svg>

<!-- 下寄せ(上に余白) -->
<svg viewBox="0 0 24 24" width="24" height="48" class="icon"
preserveAspectRatio="xMidYMax meet">
  <path d="M9 5L15 12L9 19" />
</svg>

preserveAspectRatioのsliceで切り抜く

sliceを使用すると、表示領域全体を埋めるようにスケーリングされ、はみ出した部分を切り取ります。これも余白調整として使えます。

サンプルとして利用しているアイコンはviewBoxによって幅は24となっていますが、>の形状自体はこれより細い形をしています。sliceを指定して左右の余白を切り取ってみましょう。

width24から16にしたうえで、右、左右、左の余白を切り取ってみます。

preserveAspectRatioのslice指定による余白の調整

<!-- 左に配置して右の余白を切り取り -->
<svg viewBox="0 0 24 24" width="16" height="24" class="icon"
preserveAspectRatio="xMinYMid slice">
  <path d="M9 5L15 12L9 19" />
</svg>

<!-- 中央に配置して左右の余白を切り取り -->
<svg viewBox="0 0 24 24" width="16" height="24" class="icon"
preserveAspectRatio="xMidYMid slice">
    <path d="M9 5L15 12L9 19" />
</svg>

<!-- 右に配置して左の余白を切り取り -->
<svg viewBox="0 0 24 24" width="16" height="24" class="icon"
preserveAspectRatio="xMaxYMid slice">
  <path d="M9 5L15 12L9 19" />
</svg>

sliceに関しては少々わかりづらいかもしれないので、図でも補足しておきます。

X軸の最小値にviewBoxと表示領域を揃えたうえで右側のはみ出した8px分を切り取り

X軸の中央にviewBoxと表示領域を揃えたうえで左右両側のはみ出した各4px分を切り取り

X軸の最大値にviewBoxと表示領域を揃えたうえで左側のはみ出した8px分を切り取り

デモを見てみましょう。

もとのアイコンのサイズはそのままに左右の余白が切り取られていることが確認できます。

このように、SVGのpreserveAspectRatio属性を理解して使いこなすことで、viewBoxを変更することなく、表示領域のサイズと配置指定だけで柔軟な余白調整が可能になります。

ここまでのまとめ

SVGの余白についてwidthheight、そしてpreserveAspectRatioを使って調整する方法を解説しました。

今回は記事ではviewBoxの値は0 0 24 24のままで変更することはしませんでした。次回はこのviewBoxについてもう少し詳しく解説したうえで、このviewBoxの値によって余白を調整する方法も解説します。