【CSS】疑似要素で配置するアイコン画像はbackgroundからmaskに乗り換え!

  • URLをコピーしました!
目次

先に結論

デモ

前提

主にhoverで色が変わるボタンなどで、疑似要素でアイコンを配置するときの話です。

青地に白文字のリンクボタンにリンクだと分かるようにアイコンが表示されている

アイコンの部分を除くと、以下のようなCSSになっていると仮定します。

.button{
    display: inline-flex;
    align-items: center;
    gap: 16px;
    background: #0A246A;
    color: #fff;
    padding:20px;
    line-height: 1.5;
    text-decoration: none;
    transition: background-color 1s, color 1s;
}

.button:hover{
    background: #fff;
    color: #0A246A;
}

従来

アイコン部分はbackgroundで画像を配置して、hover時のCSSで別の画像に切り替えます。

ただbackground-imageのtransitionはブラウザによって微妙に効いたり、微妙に効かなかったり、全然効かなかったり……

Chrome126ごろ:アイコンのtransitionが効いていたり効いていなかったりする様子

.button::after{
    content: "";
    width: 16px;
    height: 16px;
    background: url("chevron-white.svg") no-repeat center / contain;
    transition: background-image 1s;/* chromeでは微妙に効く */
}
.button:hover::after{
    background: url("chevron-blue.svg") no-repeat center / contain;
}

今はこれでOK

backgroundの代わりにmaskを指定すれば、画像は1枚でいいし、hover用のCSSも基本不要です。
この方法ならtransitionに悩まされることも無し。

※iOS15.4からは-webkit- いらなくなりました。
Can I Use…

.button::after{
    content: "";
    width: 16px;
    height: 16px;
    background: currentColor;/*文字色とアイコンの色が一致するならこれでOK*/
    mask: url("chevron.svg") no-repeat center / contain;
}

maskの詳細

まずアイコンを表示に使う::afterのサイズを決めて、アイコンの色をbackgroundとして指定します。
多くの場合はテキストの色と同様になるためcurrentColor を指定しておきます。(そうすることで:hover::afterの色を指定が不要になります)

.button::after{
    content: "";
    width: 16px;
    height: 16px;
    background: currentColor;/*文字色とアイコンの色が一致するならこれでOK*/
}

※display:inline-flexの中に配置しているため、display:blockを指定しなくてもwidth等が指定できます。

すると、アイコンを配置したい位置に、四角形が表示されます。

リンクボタンのアイコンの位置に白い四角形が表示されている。開発者ツールでCSSのmaskが無効になっている
maskを無効にするとアイコンの位置に四角形が表示される

次に、アイコン画像を用意します。
色は黒でも白でもなんでも良いし、SVGでもPNGでも構いません。

最後にアイコン画像をmask: url("chevron.svg") no-repeat center / contain; のように指定します。
プロパティ名以外はbackgroundに画像を指定するときと同じです。

.button::after{
    content: "";
    width: 16px;
    height: 16px;
    display: block;
    background: currentColor;/*文字色とアイコンの色が一致するならこれでOK*/
    mask: url("chevron.svg") no-repeat center / contain;
}

これで、アイコンが表示されました。

青地に白文字のリンクボタンにリンクだと分かるようにアイコンが表示されている

この方法のよいところ:CSSのみで色を変更できる

この方法だとアイコンの色は疑似要素のbackground-colorになるため

  • background-colorはtransitionが効く
  • 何色あっても画像は1ファイルでよい

というメリットがあります。

白地に赤文字のリンクボタン
急に違う色のボタンが必要になっても、画像作成不要!

この方法では対応できないパターン:アイコン内で複数色を使う

もしもアイコンがカラフルで一度に複数色を表現する場合は、maskでは表現できません。

赤色とオレンジ色の2色で作られたアイコン

まとめ

単色のアイコンかつ、サイト内でいろいろな色(hover前後など)で使う場合はmaskを利用して効率よく変更に強い実装試してみましょう!

デモ

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

目次