box-shadowの重ねがけでニュアンスのあるシャドウを実装する

はじめに

今回はCSSプロパティbox-shadowについてです。
ひとつの要素に指定したCSSで、box-shadow: 〜〜, 〜〜;のようにカンマ区切りで複数の指定を何回でも重ねてかけることができます(といっても、かけ過ぎるとレンダリングが遅くなってしまいそうですね)。

イラレやPhotoshopでデザインしたことある人はピンときましたね?
一回だけのshadowでは何ていうんだろ……こう、つまらないペラい影になってしまうところを、複数回かけることによって深みがあったりニュアンスのある理想の影を実装することができるのです。

box-shadowについて、基本的なことはまずはMDNさんのサイトで把握してください。

記述の仕方は複数あるのですが、自分が一番慣れているbox-shadow: 10px 5px 2px 2px rgba(0, 0, 255, .2);、この書き方で進めます。

box-sizingの記述の仕方

また、box-shadowは内側にも影をかけれたりするのですが、この記事では外側前提で話を進めます。

違いを見てみよう

今風のほわぁっとしたshadowをかけてみたいとします。例としてアイキャッチ画像を使用します(もちろんdiv要素にかけても問題ありません)。

白い画像なので分かりやすくboederを付けました

まずひとつがけと3つがけで比較してみます。
.shadow-sample-01がシンプルにshadowひとつがけ、.shadow-sample-02がshadow三つかけです。

box-shadow実装用サンプル画像

.shadow-sample-01
box-shadow実装用サンプル画像

.shadow-sample-02
.shadow-sample-01 {
  box-shadow: 0px 2px 20px 0px rgba(0, 0, 0, .12);
}
.shadow-sample-02 {
  box-shadow: 
    0px 1px 3px 0px rgba(0, 0, 0, .1), 
    0px 3px 15px 0px rgba(0, 0, 0, .08), 
    0px 5px 28px 0px rgba(0, 0, 0, .06);
}

重ねがけをすることによりエッヂがキリッとシャープになりましたね。
簡単に説明すると、あまりぼかさず距離も近いshadow(濃い)←→ぼかしが大きく距離も遠いshadow(薄い)となっています。
現実でも光源が近いと影が濃くくっきりし、光源が遠いと影が淡くぼんやりします。そういうイメージです。

ぼかしの大きいshadowは4つめの数値で縮小をかけた方がナチュラルかもしれません。
ひとつがけ、3つがけ、それぞれマイナスの値を付加してみます。

box-shadow実装用サンプル画像
.shadow-sample-03
box-shadow実装用サンプル画像

.shadow-sample-04
.shadow-sample-03 {
  box-shadow: 0px 2px 25px -5px rgba(0, 0, 0, .12);
}
.shadow-sample-04 {
  box-shadow: 
    0px 1px 3px 0px rgba(0, 0, 0, .1), 
    0px 3px 20px -5px rgba(0, 0, 0, .08), 
    0px 5px 40px -10px rgba(0, 0, 0, .06);
}

どうでしょう? この影のニュアンスの差、分かりますでしょうか?

実装例

ここからは実装例を並べていきます。
左がshadowの重ねかけがそのまま付加されたもの、右がhoverでshadowの重ねがけが付加されるものです(スマホでは上下になります)。

例: その1

先ほどの.shadow-sample-04です。

box-shadow実装用サンプル画像

.shadow-sample-04
box-shadow実装用サンプル画像

.shadow-sample-04-hover
.shadow-sample-04-hover {
  box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .1);
  transition: 0.3s all;
  cursor: pointer;
}
.shadow-sample-04-hover:hover,
.shadow-sample-04-hover:focus,
.shadow-sample-04-hover:active {
  box-shadow: 
    0px 1px 3px 0px rgba(0, 0, 0, .1), 
    0px 3px 20px -5px rgba(0, 0, 0, .08), 
    0px 5px 40px -10px rgba(0, 0, 0, .06);
}

hoverでかかる場合、ベースにtransition: 0.3s all;などかけておくと、じんわりshadowがかかることになります。

例: その2

ぼかしを0にし拡大することでbox-shadowでもborderのような効果を付加することもできます。

box-shadow実装用サンプル画像

.shadow-sample-05
box-shadow実装用サンプル画像

.shadow-sample-05-hover
.shadow-sample-05 {
  box-shadow: 
    0px 0px 0px 2px rgba(0, 0, 0, .1), 
    0px 6px 0 2px rgba(0, 0, 0, .05);
}
.shadow-sample-05-hover {
  box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, .1);
  transition: 0.3s all;
  cursor: pointer;
}
.shadow-sample-05-hover:hover,
.shadow-sample-05-hover:focus,
.shadow-sample-05-hover:active {
  box-shadow: 
    0px 0px 0px 2px rgba(0, 0, 0, .1), 
    0px 6px 0 2px rgba(0, 0, 0, .05);
}

hover時はshadowが重なるような記述をしているため、枠線にあたる部分が若干色が変化してしまっていますね。

例: その3

層にすることで、何重もの外枠が付いているような表現も可能です。

box-shadow実装用サンプル画像

.shadow-sample-07
box-shadow実装用サンプル画像

.shadow-sample-07-hover
.shadow-sample-07 {
  box-shadow: 
    0px 0px 0px 1px rgba(0, 0, 0, .3), 
    0px 0px 0px 3px rgba(255, 255, 255, 1), 
    0px 0px 0px 5px rgba(0, 0, 0, .3);
}
.shadow-sample-07-hover {
  box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, .1);
  transition: 0.3s all;
  cursor: pointer;
}
.shadow-sample-07-hover:hover,
.shadow-sample-07-hover:focus,
.shadow-sample-07-hover:active {
  box-shadow: 
    0px 0px 0px 1px rgba(0, 0, 0, .3), 
    0px 0px 0px 3px rgba(255, 255, 255, 1), 
    0px 0px 0px 5px rgba(0, 0, 0, .3);
}

例: その4

ここまでの例ではshadowの色を無彩色にしていましたが、若干の彩度を付けることで透明感が出すことができます。

box-shadow実装用サンプル画像

.shadow-sample-06
box-shadow実装用サンプル画像

.shadow-sample-06-hover
.shadow-sample-06 {
  box-shadow: 
    0px 1px 3px 0px rgba(130, 170, 200, .4), 
    0px 3px 20px -5px rgba(130, 170, 200, .27), 
    0px 5px 40px -10px rgba(130, 170, 200, .15);
}
.shadow-sample-06-hover {
  box-shadow: 0px 1px 3px 0px rgba(130, 170, 200, .4);
  transition: 0.3s all;
  cursor: pointer;
}
.shadow-sample-06-hover:hover,
.shadow-sample-06-hover:focus,
.shadow-sample-06-hover:active {
  box-shadow: 
    0px 1px 3px 0px rgba(130, 170, 200, .4), 
    0px 3px 20px -5px rgba(130, 170, 200, .27), 
    0px 5px 40px -10px rgba(130, 170, 200, .15);
}

box-shadowジェネレーター


あるんですね〜。
この記事では「重ねがけ」という表現を使いましたが、このジェネレーターでは「レイヤー」という表現を使っています。
右側のコンパネで調整することで、左側でshadowのかかり具合がプレビューされてリアルタイムで確認することができます。

ジェネレーターのキャプチャ
Layers of shadows レイヤーの(重ねがけする)数
Final transparency 最終的な透過度(このシミュレーターでは重ねるごとに透明になるパターンです)
shadowのトーンのイージングも調整できます。
Final vertical distance 最終的な縦軸の距離
各レイヤーの距離感のイージングも調整できます。
Final blur strength 最終的なボケ度
Reduce spread -100px〜0pxまでで調整できます(縮小のみで膨張無し)
全てのレイヤーに一括でかかります

レイヤーごとに拡大縮小の調整はできないなどできる範囲は限られてるんですが、実装のイメージを掴むには有益です。

もっと実装例を見たい方へ

いいサイトがあるんです!

現時点で実装例が86! レインボー🌈まである実験っぷり。楽しんで増やしていってますね。

なお

この記事では触れていませんが、text-shadowも重ねがけできます。
positionを使って他の要素に重ねたときなどに、文字の視認性を上げるのにいいかな?