【CSS】mask-image で自由自在!背景画像として読み込んだSVGアイコンの色を変える方法

Webサイトのボタンやリンクにアイコンを添える際、ホバー時に「文字色と一緒にアイコンの色も反転させたい!」というケースは非常によくあります。

もしアイコンを <img> タグや background-image で読み込んでいた場合、CSSから直接アイコンの色を変えることはできません。そのため、ひと昔前は「通常時の青いアイコン」と「ホバー時の白いアイコン」のように2枚の画像データをわざわざ用意して、ホバー時に画像を切り替えるという対応をしていました。

画像の切り替えは手間も負荷もかかる
画像を複数用意するのは管理の手間が増えるだけでなく、ホバーした瞬間に新しい画像を読み込むため、初回ホバー時に「一瞬アイコンが消えてチラつく」という現象が起こりがちでした。

そこで活躍するのが、CSSの mask-image プロパティです! このプロパティを使えば、SVGアイコンを「型抜き(マスク)」のように使い、background-color(背景色)を変えるだけでアイコンの色を自由に変化させることができます。

今回は、絶対に役立つこのスマートな実装方法をご紹介します!

デモ動作

See the Pen Untitled by mikanbako (@mikanbako) on CodePen.

全画面でのデモ動作は以下のリンクからご確認下さい!(別タブで開かれます)

実装コードの紹介

【HTML】

<div class="l-wrap">
  <a href="#" class="p-btn">
    サンプルボタン
  </a>
</div>

【CSS】

/* =========================================
   ボタンのベーススタイル
========================================= */
.p-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 16px 32px;
  font-size: 18px;
  font-weight: bold;
  text-decoration: none;
  
  /* ボタンの初期カラー(白背景・水色文字) */
  color: #1bb4d4;
  background-color: #fff;
  border: 2px solid #1bb4d4;
  border-radius: 8px;
  
  transition: color 0.3s ease-out, background-color 0.3s ease-out;
}

/* =========================================
   mask-image を使ったアイコン
========================================= */
.p-btn::before {
  content: "";
  display: inline-block;
  width: 24px;
  height: 24px;
  
  /* ① 色となる背景色を指定 */
  background-color: #1bb4d4;
  
  /* ② SVGアイコンで型抜き(マスク)をする */
  -webkit-mask-image: url("./icon-search.svg");
  mask-image: url("./icon-search.svg");
  
  /* ③ マスクのサイズと繰り返し設定 */
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  
  transition: background-color 0.3s ease-out;
}

/* =========================================
   ホバー時のスタイル変更
========================================= */
.p-btn:hover {
  color: #fff; /* 文字を白に */
  background-color: #1bb4d4; /* ボタン背景を水色に */
}

/* ボタンをホバーした時、アイコン(擬似要素)の背景色を変えるだけ! */
.p-btn:hover::before {
  background-color: #fff;
}

コードの解説・こだわったポイント

まるで「型抜き」! mask-image の仕組み

このプロパティの面白いところは、SVGアイコンを画像そのものとして表示するのではなく、「表示領域をくり抜くためのマスク(型抜き)」として利用する点です。

  • まず、要素全体を background-color(今回は水色)で塗りつぶします。
  • 次に、mask-image に指定したSVGアイコンの形で、その背景色を切り抜きます。
  • 結果として、「背景色」がアイコンの形になって画面に表示されます。

この仕組みのおかげで、ホバー時にアイコンの色を変えたい場合は、背景色(background-color)を変えるだけで済むようになります!

ベンダープレフィックス(-webkit-)の指定を忘れずに!

mask-image は非常に便利なプロパティですが、Safariや一部のブラウザではまだ -webkit- というベンダープレフィックス(接頭辞)が必要です。 安全に運用するためには、デモコードのように -webkit-mask-imagemask-image を必ずセットで記述するようにしましょう。

補足:参考リンク

・MDN: mask-image
・Can I Use: CSS Masks

まとめ

今回は、mask-image を活用して、外部のSVGアイコンの色をCSSだけでスマートに変化させるテクニックをご紹介しました。

「画像を2枚用意する」という古い手法から脱却することで、管理の手間が減るだけでなく、不要な画像の読み込みを防ぎ、サイトのパフォーマンス(表示速度)向上にも繋がります。

SVGアイコンを扱う際、HTML内に直接書けるなら以前紹介した currentColor を、外部ファイルとして読み込む必要があるなら今回の mask-image を使う、というように、状況に応じて最適な実装手法を使い分けられるフロントエンドエンジニアでありたいと思います。

Prev
Next