SVG画像にCSS変数を適用する

SVG画像はベクター画像標準としてWebで広く利用されています。
またSVGはXMLでもあり、加工するとCSS変数も利用できます。これにより、用途に応じて色を変えられる画像を作れます。

CSS変数を用いるためのインクルード形式

SVG画像を表示するタグは複数あり、一般的なimgタグでインクルードした場合には画像内の制御はできません。

<!-- 通常のインクルード -->
<img src="sample.svg" />

<!-- CSS変数が効くインクルード -->
<svg style="--img-color: blue">
  <use href="sample.svg#img" />
</svg>

ただし、useタグでインクルードするためには、svgファイルを書き換える必要があります。
変更したファイルは、Inkscapeなど一部のアプリで編集できない形式になります。

useタグでインクルードできるsvgマークアップ

useタグはSVG画像内のsvg > defs > symbolを参照します。
多くの画像編集ソフトはdefssymbolを含まない形式で直接gpathを書き出すため、テキストエディタでタグを追加します。

また、defsタグ内はレンダリングされないため、svgファイル内にもuseタグを追加しておくと、<img />でもインクルードできる形式になります。
以下のような構造になります。

<svg>
  <!-- 一般的な画像としても表示可能にするためuseを追加 -->
  <use href="#img" />

  <!-- useタグ用に defs と symbol でラップ -->
  <defs>
    <symbol id="img" viewBox="0 0 200 100">
      <!-- 画像編集ソフトが出力した画像データ -->
      <g>
        <!-- 外部から制御したい部分をCSS変数に置き換え -->
        <path fill="var(--img-color, #888888)" />
      </g>
    </symbol>
  </defs>
</svg>

g > pathの部分が画像で、色などは各描画要素に指定されています。
CSS変数を利用したい場合には、テキスト置換で色を変数に置き換えます。 CSS変数は第2引数を指定でき、元の色を設定しておくと<img />タグなどでインクルードした際にフォールバックで使われます。

なお、viewBox属性は多くの場合svgタグに記載されていますが、symbolに移しておいた方が使いやすいでしょう。

⁋ 2021/10/10↻ 2024/12/18
中馬崇尋
Chuma Takahiro