CSSで色変更もできるSVGアイコンを使うための3ステップ

SASS/SCSSで使いまわせる!CSSで色変更もできるSVGアイコンを使う方法 CSS

こんにちは。みみほくろです。

Webデザインでアイコンをつけたいとき、何を使いますか?

画像を読み込む、疑似要素を使って描画などがよくある方法かと思いますが、今回はSVGを使ったアイコン表示について紹介します。

SVGとは

SVGはWebに適したベクターファイル形式の画像フォーマットの一つで、拡大縮小してもPNG画像やGIF画像のように解像度を損なうことがないという大きなメリットを持ちます。

また、図形をテキストで情報を保持しているため、ファイルサイズが小さく、テキストとしてSEO的にも効果があることもメリットの一つです。

ただ、写真のような複雑な画像には適していないので、アイコンのようなシンプルな画像に使うことが主な使用用途になります。

SVGの中身を見ると、簡単な図形であっても一見複雑なためにかなり取っつきにくく感じると思います。が、基本的に内容を大きく変えることはないので、画像自体のサイズや色などの調整ができれば十分です。

調整なくそのままでも使えますが、最適化することでさらにファイルサイズの縮小ができSEOへの影響も期待できます。

SVGの構造

それでは基本的なSVGファイルのコードを見ていきましょう。

アイコンはGoogle Iconsから引用
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>

シンプルな形状のアイコンでもコード上で見るとなかなかに複雑ですね。

SVGアイコンに色情報を付与する

Google Iconsから取得したままの状態だと色情報を持っていないので、fill属性を使って色情報を与えます。

<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48" fill="#ff0000"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>

svgタグにfill属性を付与しました。この場合アイコンが赤色(#ff0000)になります。

これで色変更ができるSVGアイコンの基本形ができました。

SVGをCSSで色変更するための3ステップ

お待たせしました、ようやく本題です。

SVGはHTMLにインラインで記述もできますが、今回は疑似要素を使ってご紹介します。

.svg::before {
  content: "";
  display: block;
  width: 48px;
  height: 48px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48" fill="%23ff0000"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>');
  background-size:100%;
  background-repeat: no-repeat;
}

一見SVGファイルのコードをそのまま貼り付けたように見えますが、3つポイントがあります。

  • data:image/svg+xml;utf8
  • 包括するクォーテーションはシングル
  • 色コードの #%23 に変更する

data:image/svg+xml;utf8

本来外部ファイルとして読み込むSVGファイルをインラインコードで埋め込むために必要なものです。今回のようなCSSでSVGを使う場合は必須です。

utf8は文字コードなので必要に応じて書き換えてください。

包括するクォーテーションはシングル

これはSVGファイルのコードにダブルクォーテーションが使われているので、その上からダブルクォーテーションで囲ってしまうとコードを分割したと判断されてしまうのでシングルクォーテーションで囲う必要があります。

ちなみにsvgタグ内のクォーテーションをすべてシングルにして、svgタグを囲うクォーテーションをダブルにしてもOKですが、Google IconsでダウンロードしたものやPhotoshopなどで書き出したSVGファイルはsvgタグ内にダブルクォーテーションが使われているケースがほとんどなので、svgタグを囲うクォーテーションはシングルがおすすめです。

色コードの#を%23に変更する

かなり地味ですが、これが今回のキモです。

今回のようなアイコンを表示するためにbackground-imageでURLを指定してSVGファイルを読み込む場合、カラーコードを示す # は使えません。

そのため、URLエンコードを使って# の代わりに%23に変換することで色コードを表現することができます。

上記のコードでは「#ff0000」を「%23ff0000」に変換しています。

複数個所で使うならSCSS/SASSで共通化が便利!

ここからはSCSS/SASSを使った便利な方法のご紹介です。

複数個所で使う場合、すべてコピペするのはナンセンスですし、いざ変更が入ったときにすべて修正するのは大変です。

SCSS/SASSにはよく使うコードを共通化できるmixinという機能があって、使いたい箇所で呼び出すと定義してあったスタイル一式をCSSにコンパイルした時に出力してくれる便利な機能です。

mixinは引数も渡せるので、今回のような色だけ変更したいけど他は同じものを表示したいよ、というときにもよく使います。

コード

@mixin svgIcon($baseColor: "dddddd") {
  width:48px;
  height:48px;
  display: block;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48" fill="%23#{$baseColor}"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>');
  background-size:100%;
  background-repeat: no-repeat;
}

.svg {
  &::before {
    content: "";
    @include svgIcon($baseColor: "00ff00");
  }
}

@mixinでスタイルを一式定義(この場合svgIcon)して、@includeで定義したスタイルをカラーコード#00ff00(緑色)を引数として渡して呼び出します。

引数はsvgタグの色コードの部分に割り当ててあるので、この場合カラーコード#00ff00のSVGアイコンが表示されます。

さらにmixinは初期値も持たせることができるので、色の指定がなければ初期値の色で表示させることが可能です。この場合#ddddddを初期値として設定しています。

応用編

ここからはさらにテクニカルな方法をご紹介します。

文字列を一部だけ抽出するstr-slice関数

SCSS/SASSにはstr-sliceという指定の位置の文字列を抽出する便利な関数が存在します。

詳しい使い方はこちらの記事で紹介しています。

SCSS/SASSを使うとき、よく色コードを変数に格納して使うことが多いと思いますが、コンパイルすると「#」も含んでいるため上記でご紹介した方法でSVGが使えません。

そこで、str-sliceで変数から#を除いた色コードだけを抽出して、定義したmixinに渡すことで直接色コードを指定することなく使いまわせます。

str-slice関数を使ったコード

変数に色コードを格納し、mixinで使いまわせるように定義したコードがこちら!

$svg-color: #0000ff;

@mixin svgIcon($baseColor: "#dddddd") {
  display: block;
  width:48px;
  height:48px;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48" fill="%23#{str-slice(#{$baseColor}, -6)}"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>');
  background-size:100%;
  background-repeat: no-repeat;
}

.svg {
  &::before {
    content: "";
    @include svgIcon($baseColor: $svg-color);
  }
}

ちなみにこれをコンパイルするとこうなります。

.svg::before {
  content: "";
  width:48px;
  height:48px;
  display: block;
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48" fill="%230000ff"><path d="M796-121 533-384q-30 26-69.959 40.5T378-329q-108.162 0-183.081-75Q120-479 120-585t75-181q75-75 181.5-75t181 75Q632-691 632-584.85 632-542 618-502q-14 40-42 75l264 262-44 44ZM377-389q81.25 0 138.125-57.5T572-585q0-81-56.875-138.5T377-781q-82.083 0-139.542 57.5Q180-666 180-585t57.458 138.5Q294.917-389 377-389Z"/></svg>');
  background-size:100%;
  background-repeat: no-repeat;
}

いかがでしたでしょうか?

SVG画像はほとんどのブラウザでサポートするようになりましたし、Google Iconsのような商用OKで無料提供しているサイトも多数あって、非常に便利になりました。

この記事を読んでSVGアイコン使ってみようと思っていただけると嬉しいです!

タイトルとURLをコピーしました