12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NIJIBOXAdvent Calendar 2019

Day 24

CSSにおけるシャドウ効果の影

Last updated at Posted at 2019-12-24

対象読者

  • 「このシャドウはCSSで再現可能かな?」とお悩みのデザイナーの方
  • 「このシャドウどうやってCSSで再現しよう、、」とお悩みのフロントエンドの方

注意

  • Sass芸(Sassの@for等を利用して、複雑な形を再現したりする行為)ではなく、無理なく使える範囲を狙います
  • IEには疲れたのでこの記事中では存在しないことにします
  • 作例はPug + Stylusで作成しています

htmlの要素にシャドウをつけたいという欲求

に対する一番シンプルな答えは、CSSのbox-shadowプロパティですね。
これを利用することで、要素のフレームの周囲にシャドウ効果を追加できます。

ただ、これはCSSの中でも扱いが難しいプロパティかと思います。
苦い顔をしてしまう方も多いのではないでしょうか?

box-shadowの憂鬱

というのも、Adobe XDなど、デザインツールは矩形でなくとも様々な効果を設定することができるためです。

一方のCSSはボックスモデルに基づき、矩形の領域をベースにスタイリングを行いますから、デザインの再現に無理が発生してきます。

その際、box-shadowは、同じくボックスモデルの周囲を装飾するborderと比べ、左右上下での調整が効きにくく、綺麗に表現するには工夫が必要な場面が出てきがちです。

CSSにおけるシャドウ効果は一筋縄ではいかない、、、そう、があるということです。
※個人の感想です

この記事では、そんなシャドウ効果の一端をご紹介します。

Lv.1 矩形の要素

box-shadowを設定するのみです。

See the Pen Lv1.box-shadow by haradabox (@haradabox) on CodePen.

問題ないですね。

Lv.2 凸形の要素(タブ風UI)

タブ選択で表示するコンテンツの切り替えができるUIを考えます。
選択しているタブと、コンテンツの周囲をシャドウで囲いたい、、、という欲求です。

ここからややこしくなってきます。

まず下記をご覧ください。

無邪気に

See the Pen Lv2.box-shadow--faild by haradabox (@haradabox) on CodePen.

タブ要素、コンテンツ要素共に周囲にシャドウを付けていますが、タブ要素にコンテンツ要素のシャドウが被ってしまっています。

これではいけませんね。

少し考えて

擬似要素とz-indexを利用し、被っているシャドウを消しました。

.box
  position: relative;
  z-index: 0;
  &__tab-item    
    &.--current
      position: relative;
      box-shadow: 0 1px 3px 0 #333;
      background-color: #fff;
      // コンテンツのシャドウを隠す
      &::after {
        position: absolute;
        bottom: 0;
        left: 0;
        height: 3px;
        width: 100%;
        content: "";
        background-color: #fff;
        z-index: 3;
      }
  &__body
    position: relative;
    z-index: 2;
    background-color: #fff;
    box-shadow: 0 1px 3px 0 #333;

See the Pen Lv2.box-shadow by haradabox (@haradabox) on CodePen.

よろしそうですね。

Lv.3 凹形の要素(チケット風UI)

お次は凹形の要素です。
チケットのような、切り欠きのある形を再現します。

惜しい

See the Pen Lv3.box-shadow--failed by haradabox (@haradabox) on CodePen.

丸い切り欠きの表現に、before擬似要素 + borderを使いました。
それっぽくはありますが、もうちょいいけそうですね?

それなりに

before擬似要素ではinsetのbox-shadowで円形のシャドウを作成します。
そして、背景色のbox-shadowを加えた、after擬似要素で、不要な箇所をマスクします。

See the Pen Lv3.box-shadow by haradabox (@haradabox) on CodePen.

よりそれっぽくなりました。

Lv.4 ギザギザ形の要素(アイコンと一体に)

Sass芸縛りプレイなので、rotateとskewを駆使して、、、という案は無視します。
となればSVGなんですが、、、

どうやってシャドウをつければいいのだっけ?

drop-shadowはボックスモデルに対して影がつくので、、、

See the Pen Lv4.box-shadow--svg-fail by haradabox (@haradabox) on CodePen.

まあこうなりますよね。

filterを使う

SVGには強い味方、filter: drop-shadowがあります。

表示したいSVGを前面に、シャドウ用のSVGを背面に配置し、シャドウで囲みたい部分(コンテンツなど)を挟み込みます。
また、filter: drop-shadowのプロパティはbox-shadowとは異なるため、数値は微調整します。

.box
  position: relative;
  z-index: 0; // シャドウが親要素の後ろに入り込まないように付与
  &__inner
    position: relative;
    border-radius: 8px;
    padding: 50px;
    background: #fff;
    box-shadow: 0 1px 3px 0 #333;
    z-index: auto; // 指定なしでもOKですが、回り込ませる対象としてわかりやすいかなーということで付与
  &__icon
    width: 100px;
    position: absolute;
    top: 0;
    left: 0;
    transform: translate(-30px, -30px);
    &.--shadow
      z-index: -1; // シャドウ用のSVG画像を.box__innerの後ろに回り込ませる
.svg-icon.--shadow
  filter: drop-shadow( 0 1px 1px #444); // filterでSVG画像に沿ったシャドウを付与

See the Pen Lv4.box-shadow--svg by haradabox (@haradabox) on CodePen.

私は満足です。

おまけ: ロングシャドウ

完璧ではないのですが、お蔵にするには勿体無いので、記載しておきます。

それがこちらです

.box
  position: relative;
  z-index: 0;
  &__inner
    position: relative;
    background: #fff;
    z-index: auto;
    &::before
      content: "";
      position: absolute;
      top: -1px;
      left: 0;
      width: 300px;
      height: 100%;
      transform: skew(0, 45deg);
      transform-origin: 0 0;
      background: linear-gradient(90deg, rgba(200,200,200,1) 0%, rgba(255,255,255,1) 100%);
      z-index: -1;
    &::after
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 300px;
      box-sizing: border-box;
      transform: skew(45deg);
      transform-origin: 0 0;
      background: linear-gradient(180deg, rgba(200,200,200,1) 0%, rgba(255,255,255,1) 100%);
      z-index: -1;

See the Pen extra.long-shadow by haradabox (@haradabox) on CodePen.

before擬似要素/after擬似要素でシャドウを作成します。 それぞれがシャドウを付与したい要素のheight/widthに依存し、skewで歪めることで汎用性のあるシャドウにしています。

グラデーションの角度調整(グラデーションの終端が要素の形になってしまう)が課題ですね。

まとめ

シャドウ効果はこんな感じで工夫が求められることが多いです。
しかしながら、裏を返せば工夫の発揮しどころ、実装を楽しめるポイントでもあります。

「他にもこんなシャドウ再現できまっせ」、ありましたら是非コメントをば!

12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?