PerfectVector
著者: Irene Kim2 分で読める

インラインSVGとimg:画像に必要な動作で組み込み方を選ぶ

同じSVGを画像とインラインマークアップで比較します。CSSの色制御、サイズ、アクセシブルな名前、再利用を試して組み込み方を選びます。

目次

完成した画像を表示するには、<img>要素でSVGを使います。ページからCSSやJavaScriptで個々の形状を変える必要がある場合は、SVGをインラインに置きます。どちらも同じベクター画像を異なるサイズで表示でき、インラインにしても形状の品質は向上しません。

ブラウザーのタブではロゴが正しく見えるのに、Webサイトの色の規則を無視する場合、この違いが重要です。ファイル自体は正常かもしれません。規則から内部へ届かないだけの場合があります。以下では、同じ山のイラストを両方の形式で表示し、素材の処理を変える前に違いを確認します。

必要な動作を選ぶ

要件最初に使う方法確認するもの
完成したロゴやイラストの表示<img>の外部SVG自身の色、寸法、代替テキスト
UI状態に応じて1つの形を変えるインラインSVGその形へ届く範囲を限定したセレクター
同じ画像をページ間で再利用<img>の外部SVG素材URLとサーバーのキャッシュ方針
イラスト全体をリンクにするどちらかをHTMLリンク内に置くリンクのアクセシブルな名前とフォーカス動作
PNGから編集可能な形状を復元まずベクター化組み込み方法を選ぶ前に結果のパス

外部SVGは、<img>で表示してもベクターファイルのままです。境界があるのは、ページとファイル内部の要素の間です。ページのCSSは画像要素をリサイズ、回転、フェードできますが、.logo pathのようなセレクターはsrcリソース内のパスへ届きません。インライン形状はページの文書ツリーの一部になります。MDNのSVG組み込みガイドが、2つの方法を説明しています。

まだファイルの中身を調べている場合は、SVGファイルとは何かから始めます。.svgという拡張子だけでは、見えるすべての細部がパスだとは言えません。ストアへの受け渡しでは、内容を確認してからShopifyの独自SVGアイコンガイドに従います。

同じ画像を両方の形式で試す

このデモ用に、2本の山のパスと1つの太陽の円を手書きしました。別ファイルから画像を読み込み、同じ形をHTMLへ貼り付けました。組み込みのテストであり、PerfectVectorの変換結果ではありません。

Chromiumのブラウザーテストでは、両方とも最初は360 × 240 CSSピクセルで、太陽は琥珀色でした。次に.sunを対象にしたページの規則を有効にしました。インラインの太陽はコーラルへ変わり、外部画像の太陽は琥珀色のままでした。両方のボックスを180 × 120へ縮めると、表示サイズだけが変わり、この違いは残りました。

同じページCSSを適用した後、外部SVG画像の太陽は琥珀色、インラインSVGの太陽はコーラルになるブラウザー比較
同じ手書き画像にページCSSを適用した結果です。色が変わるのはインラインの太陽だけで、両方の比率は同じままです。

1. 別のSVGファイルを保存する

この完全な内容でartwork.svgを作ります。viewBoxは描画の座標空間を定義し、幅と高さは明示的な初期寸法を与えます。

<svg xmlns="http://www.w3.org/2000/svg"
     width="240" height="160" viewBox="0 0 240 160">
  <path d="M34 120 104 26 174 120Z" fill="#233b63" />
  <circle class="sun" cx="183" cy="43" r="20" fill="#f59e0b" />
  <path d="M80 120 146 59 210 120Z" fill="#65a7a0" />
</svg>

2. 画像とインラインのコピーを加える

artwork.svgの横に、次をindex.htmlとして保存し、ブラウザーで開きます。2つの画像は形状と描画属性が同じです。インライン版には支援技術向けの名前もあります。

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>SVG embedding test</title>
<style>
  .artwork {
    display: block;
    width: 360px;
    max-width: 100%;
    height: auto;
  }
  .theme .sun { fill: #d94862; }
</style>
<body class="theme">
  <h1>External image</h1>
  <img class="artwork" src="artwork.svg"
       width="240" height="160"
       alt="Mountain and sun illustration">
 
  <h2>Inline SVG</h2>
  <svg class="artwork" xmlns="http://www.w3.org/2000/svg"
       width="240" height="160" viewBox="0 0 240 160"
       role="img" aria-labelledby="mountain-title">
    <title id="mountain-title">Mountain and sun illustration</title>
    <path d="M34 120 104 26 174 120Z" fill="#233b63" />
    <circle class="sun" cx="183" cy="43" r="20" fill="#f59e0b" />
    <path d="M80 120 146 59 210 120Z" fill="#65a7a0" />
  </svg>
</body>
</html>

スクリーンショットは、同じ形状の周囲にスタイル付きの比較レイアウトを使います。上の小さな例は挙動を再現しやすくしています。

3. 1つずつ変える

bodyからclass="theme"を削除し、再読み込みします。両方の太陽が琥珀色になるはずです。クラスを戻すと、インラインの太陽だけがコーラルになります。.artworkをwidth: 360pxからwidth: 180pxへ変えると、コンテナーに余裕がある場合、両方とも180 × 120へ縮むはずです。

外部画像の太陽の色を永久に変えるなら、artwork.svgのfillを編集します。ページ状態へ反応させたいなら、インラインのマークアップか、別の意図した配信方法を選びます。SVGの色変更ガイドは、ファイル自体の編集を扱っています。

.sunという名前はこの例用に追加したものです。変換や書き出しをしたファイルに、意味のある部品ごとの便利なクラスがあるとは限りません。見えるオブジェクトが1つの選択可能なパスだと想定せず、操作したい形を調べて名前を付けます。

サイズとアクセシブルな名前を明示する

HTMLへ移すときもviewBoxを保持します。適切な基準として幅と高さの属性を設定し、レスポンシブなCSSを適用します。この3:2のイラストでは、width: 180px; height: autoが比率を保ちます。viewBox内の大きな余白は、どちらでも描画領域の一部です。組み込み方を変えても取り除けません。

レイアウトボックスの比率が異なる場合は、preserveAspectRatioの配置ガイドが全体を収める、切り抜く、変形する方法を比較しています。

意味のある外部画像には、HTMLの<img>にaltを書きます。意味のあるインライン画像には、この例ではrole="img"と、<title>を参照するaria-labelledbyを使います。インラインSVGはHTML画像のalt属性を使いません。MDNのHTML内のSVGガイドが、これらの名前付けを説明しています。

インラインの例を繰り返すなら、title IDをそれぞれ一意にし、対応するaria-labelledbyを更新します。グラデーション、マスク、クリッピングパスのIDも同様です。同等の見える文字の横の装飾画像には、<img>の空のaltを使うか、aria-hidden="true"でインラインSVGを支援技術から隠します。リンクやボタン全体を文脈でテストし、目的の名前が残るようにします。

多数の再利用アイコンには、SVGのsymbolスプライトが別の定義とインスタンスの方法を提供します。大量のコピーを各ページへ貼る前に、その再利用が必要か判断します。

性能は測定して判断する

インラインのマークアップは、画像を別リソースとして取得せず文書内へ置きます。その分、文書のマークアップも増えます。外部ファイルは、URL、応答ヘッダー、キャッシュ状態に応じてブラウザーのキャッシュから再利用できます。MDNのHTTPキャッシュガイドが条件を説明しています。

どちらの事実も、どちらがページを速くするかは証明しません。実際のコピー数とSVGの複雑さで、初回と再訪時のページを比較します。このデモは描画へのアクセスとサイズを試すもので、読み込み速度のベンチマークではありません。

外部画像モードにはCSS以外の制限もあります。MDNは、画像として使うSVGではJavaScriptが無効になり、外部リソースが制限されると説明しています。欠けた機能を動かすためだけに、よく分からないSVGをインラインへ移さないでください。信頼できないマークアップは、ページへ組み込む前に確認してサニタイズします。

開始画像がPNGしかない場合

必要な形状が元データにないなら、組み込み方を選ぶ前にベクター化します。適したラスターのロゴやイラストでは、PerfectVectorでPNGをSVGへ変換し、結果を元画像と比較して、承認したSVGを画像マスターにします。クラスを追加したりWeb用コピーを準備したりする前に、輪郭、穴、小さな色領域を確認します。

PerfectVectorはベクター画像を提供します。CSSへ反応させる部分の選択、意味のある名前の追加、最終ページのテストは別に行います。画像の変換で、意味的なクラス名のあるコンポーネントが自動生成されるわけではありません。既存SVGに使えるパスがあれば、描画したコピーをトレースせず、そのパスで作業します。

埋め込みラスター画像を含むSVGも確認します。インラインへ貼ると<image>要素はページに現れますが、内部のピクセルが個別に色を変えられる形状になるわけではありません。写真の見た目を保つなら、適したラスターの納品形式を保持します。

最終ページを確認する

  • ページCSSのテスト前に、単独の画像が正しく見えるか確認します。
  • 完成画像の表示には<img>、要素を直接制御するにはインラインSVGを選びます。
  • 対応する最も狭いレイアウトで、描画サイズと比率を確認します。
  • 色を変えたい正確な形状を試し、広いpath規則に頼らないようにします。
  • 画像の名前、重複ID、周囲のリンクやボタンを確認します。
  • 判断に影響するなら読み込みを測定し、この例から速度を推測しないようにします。

よくある質問

imgタグで使うとSVGはビットマップになりますか? いいえ。imgから読み込んだSVGもベクター形状を描画できます。画像要素はホストページから内部形状の直接選択を防ぎますが、形状をPNGへ変換しません。

currentColorがページの文字色に従わないのはなぜですか? 外部SVG画像には独自のスタイル環境があります。ページのcolorが、そのファイル内のcurrentColorに自動でなるわけではありません。描画をページから継承させるならインラインSVGを使い、対象の塗りやストロークにcurrentColorを指定します。

既存SVGをインラインにする前に変換するべきですか? 必要なベクター形状がすでにあれば、変換は不要です。マークアップを確認し、必要な参照を保持して適切な名前を付け、ページで試します。ラスターからベクターへの変換が必要なのは、ラスターの元画像から形状を復元する場合だけです。

参考資料

  1. MDN — HTMLへのベクター画像の組み込み — 外部画像とインラインの組み込み動作。
  2. MDN — HTML内のSVG入門 — インラインマークアップ、viewBox、アクセシブルな名前。
  3. MDN — HTTPキャッシュ — 応答方針とリソースの識別に依存するキャッシュ再利用。
  4. MDN — 画像としてのSVG — 画像環境でのスクリプトとリソースの制限。

画像の役割に合う組み込み方を選び、ページの実際のスタイルで試します。適したPNGしかないなら、先にベクター形状を復元し、結果を確認して、承認した画像をその組み込み方に合わせて準備します。

ブログのその他の記事

編集しやすい
よりきれいなSVGから始めましょう