CSS filter - 画像に沿って影をつける
create: 2018-10-14
CSS Filter

CSS だけで、画像に沿って影をつけたい!

box-shadow しか知らないあなたへ

つい最近まで私もそうでしたが、img タグの画像に影を付けるときはbox-shadowを使っていました。
皆さんご存知の通り、box-shadowでは画像の内容がどうであれ、画像の外枠にしか影が付きません。
しかし最近、いろいろ SVG や透過 PNG 画像を扱うようなり、画像の形を活かして影をつけたい要望も増えてきました。

そこで今回は画像の形で影を落とす、CSS のfilter: drop-shadow関数を使ってみます。

まずは box-shadow のおさらい

まずは通常のbox-shadowです。

<!-- box-shadow -->
<img class='box-shadow' src='/images/site/cat.svg' title='SVGねこ'/>
/* box-shadow */
.box-shadow {
  box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.6);
}
.box-shadow:hover {
  box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.6);
}

ご覧のように、SVG の外枠(box)に影が設定されます。
SVG、PNG ともに猫の形が活きていませんね。
クライアントも「そうじゃないヨ!」と激怒することでしょう。

filter: drop-shadow

そこでfilter: drop-shadowの出番です。
filter 属性にdrop-shadow関数を渡して影を作ります。
ついでにマウスホバーで影を固くする効果も入れてみました。

<!-- filter-shadow -->
<img class='filter-shadow' src='/images/site/cat.svg' title='SVGねこ'/>
/* css:filterでdrop-shadow */
.filter-shadow {
  filter: drop-shadow(10px 10px 10px rgba(0, 0, 0, 0.6));
}
.filter-shadow:hover {
  filter: drop-shadow(3px 3px 0px rgba(0, 0, 0, 0.6));
}

ご覧の通り、SVG、PNG ともに猫の形に沿って影が設定されています。キレイ!

正確には「形に沿って」影が表示されるではなく、「アルファチャンネルに従って」表示されます。
「アルファチャンネル」というのは透過度のことで、透明なら影がつかない、不透明なら影がつくというルールに従って影が設定されます。今回の猫画像の場合はネコ以外は透明なので影がつかないということになります。
今回は SVG のみサンプルとしていますが、PNG も同様の効果です。

2019/11/21追記
Markdownからブログを生成するようになってからうまく影が切り抜かれていなかった減少がありました。  
原因はgithub Markdown CSSで持つ .markdown-body img {background-color: #fff;} のせいでした。
アルファチャンネルを設定していても、CSSスタイルで背景を上書きできてしまうので注意。

IE、Edge での対応状況

IE11 ではfilter: drop-shadowが効きませんでした。
ブログヘッダー部のテキスト、猫も影無しで表示されます。

caniuse.comで調べてみても、IE11 は非対応となっています。
プロダクションで使うときには対応ブラウザに注意しないといけないですね。

Edge の場合、ヘッダー部は表示されましたが:hoverで影のプロパティを変更している画像では効いていませんでした。

filter:drop-shadow リファレンス

MDN のサイトが参考になります。
drop-shadow()

ねこ画像 by 素材 Library.com, Thanks!!