マスクメロンのイラスト

SVG アイコンの表示に mask-image CSS プロパティを使用する

mask-image プロパティは CSS でマスキングを行うためのプロパティであり、SVG アイコンを表示する際に有用です。mask-image プロパティを使用することで、外部の SVG ファイルを読み込みつつ、アイコンの色を CSS で指定することが可能になります。

HTML でロゴやアイコンを表示する時、SVG はよく使われるフォーマットです。SVG はベクター形式で記述されるため、拡大・縮小しても画質が劣化しないという特徴があります。SVG を HTML で表示する場合、以下のような方法が使われていました。

  • <img> 要素の src 属性に SVG ファイルのパスを指定する
  • <svg> 要素を直接記述する
  • svg スプライトを使用する

それぞれの方法にはメリット・デメリットが存在します。<img> 要素を使用する場合には単に画像として扱われるため、アイコンの色を変えたりなどのスタイルが難しく、また JavaScript による操作も制限されます。

<svg> 要素を直接記述する場合には、fill=currentColor 属性を指定することで CSS により色を変更できたり、JavaScript による操作も可能ですが、アイコンが多くなるにつれて HTML のファイルサイズが肥大化する問題があります。また HTML に直接記述するため HTML が複雑になりがちです。

svg スプライトは 1 つの SVG ファイルに複数のアイコンを記述し、<use> 要素で参照する方法です。必要なアイコンは 1 箇所にまとめられるため、HTML ファイルの煩雑化を防ぎつつ、アイコンの色変更など SVG 自体が持つ恩恵を享受できることがメリットです。SVG スプライトを作成するためのビルドプロセスが複雑になることがデメリットです。

mask-image プロパティを使って SVG アイコンを表示する

2023 年にすべてのモダンブラウザでサポートされるようになった1mask-image プロパティは新しく SVG アイコンを表示するための方法として注目されています。mask-image プロパティ CSS でマスキング(マスキングは要素の一部を消去せずに非表示にする仕組み)を行うためのプロパティの 1 つです。mask-image プロパティはマスクレイヤーとして使用される画像を指定します。

<button aria-label="star">
  <div class="icon"></div>
</button>
 
<style>
  .icon {
    width: 24px;
    height: 24px;
    mask-image: url("./star.svg");
    background-color: aqua;
  }
</style>

上記の例では、mask-image プロパティに url("./star.svg") で外部の SVG ファイルを指定しています。アイコンの色を指定するために background-color プロパティを使用しています。以下のようにアイコンが表示されることが確認できます。

mask-image プロパティを使用することで、外部ファイルの SVG アイコンを読み込みつつ、アイコンの色を CSS で指定するということが可能になります。これは <img> 要素で読み込む方法とインライン SVG を使用する方法のメリットを組み合わせたような手法と言えるでしょう。

以下のように、ボタンにホバーした時にアイコンの色が変わるようにすることも可能です。

button {
  &:hover,
  &:focus {
    .icon {
      background-color: pink;
    }
  }
}
 
.icon {
  width: 24px;
  height: 24px;
  mask-image: url("./star.svg");
  background-color: aqua;
  transition: background-color 0.3s;
}

CSS マスキングに関するプロパティは他にも以下のようなものがあります。

  • mask-position:マスク画像の位置を指定する
  • mask-repeat:マスク画像の繰り返し方法を指定する。デフォルトでは repeat
  • mask-size:マスク画像のサイズを指定する
  • mask-clip:マスク画像が影響される領域を指定する。デフォルトは border-box
  • mask-composite:マスク画像の合成方法を指定する。デフォルトは add で現在のマスクレイヤーがそのため、の下にあるマスクレイヤーの上に配置される
  • mask-mode:マスク画像をアルファもしくは輝度のどちらで扱うかを設定する。デフォルトは alpha
  • mask-origin:マスク画像の原点を指定する。デフォルトは border-box

mask-image プロパティの値として外部ファイルを指定する代わりに、<svg> 要素を直接記述することもできます。

.icon {
  width: 24px;
  height: 24px;
  mask-image: url("data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg">...</svg>");
  background-color: aqua;
}

backgroundlinear-gradient を指定することでグラデーションのアニメーションを適用することも可能です。

.icon {
  width: 24px;
  height: 24px;
  mask-image: url("./star.svg");
  background: linear-gradient(90deg, #2dd4bf, #3b82f6);
}

まとめ

  • 従来は SVG アイコンを表示するために以下の方法が使われていた
    • <img> 要素の src 属性に SVG ファイルのパスを指定する
    • <svg> 要素を直接記述する
    • svg スプライトを使用する
  • mask-image プロパティを使用することで、外部ファイルの SVG アイコンを読み込みつつ、アイコンの色を CSS で指定することが可能になる

参考

参考

Footnotes

  1. ベースライン2023 年  |  Blog  |  web.dev

記事の理解度チェック

以下の問題に答えて、記事の理解を深めましょう。

SVG 画像を表示する際に img 要素を使う際のデメリットとして正しいものはどれか?

  • アイコンの色を変更することが難しい

    正解!

    img 要素を使う場合、CSS でアイコンの色を変更することができないため、アイコンの色を変更する場合には別の画像を用意する必要があります。

  • HTML ファイルのサイズが肥大化する

    もう一度考えてみましょう

    インライン SVG を使用する場合のデメリットです。

  • アイコンの管理が煩雑になる

    もう一度考えてみましょう

    外部ファイルとして SVG を読み込む場合には、ディレクトリ構造で管理が可能であるため煩雑になるとはいいにくいでしょう。

mask-repeat プロパティのデフォルト値はどれか?

  • no-repeat

    もう一度考えてみましょう

  • repeat

    正解!

  • repeat-x

    もう一度考えてみましょう

  • repeat-y

    もう一度考えてみましょう


Contributors

> GitHub で修正を提案する
この記事をシェアする
はてなブックマークに追加

関連記事