ジャンルから探す

Web Design English

CSSで影をつける方法は?box-shadow・text-shadow・drop-shadowの使い分け

CSSで影をつける方法は、box-shadow・text-shadow・filter: drop-shadow()の3つです。結論から書くと、要素の四角い箱に影を落とすならbox-shadow、文字に影を落とすならtext-shadow、切り抜き画像やアイコンの形に沿った影が欲しいならdrop-shadow()を使います。

どれも1行で書けますが、値の並び順と「影が何の形になるか」が違います。ここを取り違えると、透過PNGに影をつけたつもりが四角い影になってしまいます。この記事では3つの書き方と使い分けを、CodePenの実例と、2026年10月9日に手元のChrome 154・Firefox 157・WebKit 27.2(macOS 26.5.1)で表示を撮って確かめた結果つきでまとめました。

スポンサーリンク

基本1:box-shadowを実装する方法

要素に影を付けるプロパティがbox-shadowです。影は要素のボックス(四角形)の形になります。角丸を指定していれば、影も角丸に沿います。

▼box-shadowの値の並び順

box-shadow: [inset] 水平方向のオフセット 垂直方向のオフセット [ぼかし半径] [広がり] [色];

▼それぞれの値の意味

値 省略 意味
inset 可 付けると影が要素の内側に落ちる。書くなら先頭
水平方向のオフセット 不可 影を右へずらす距離。負の値で左へ
垂直方向のオフセット 不可 影を下へずらす距離。負の値で上へ
ぼかし半径 可 大きいほどぼける。0でくっきりした影になる
広がり(spread) 可 影のサイズそのものを拡大縮小する。負の値で縮む
色 可 省略するとcolorプロパティの値が使われる

必須なのは水平・垂直のオフセット2つだけです。2つしか書かなければ、ぼかしなしのくっきりした影になります。

.shadow-box {
  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3);
}

画像に影をつける

See the Pen
box-shadow
by りん@エンジニア (@rinblog0408)
on CodePen.

画像やタグ要素にくっきりした影を落とすなら、ぼかし半径を0にして色を指定します。

.shadow {
  box-shadow: 10px 10px 0 #c3a400;
}

内側に影をつける(inset)

結論:inset を先頭に書くと、影が要素の内側に落ちます。くぼんで見せたいときに使います。

/* 上から内側に影を落として、くぼんだように見せる */
.inner-shadow {
  box-shadow: inset 0 6px 10px rgba(0, 0, 0, 0.5);
}

入力欄をくぼませる場合は、内側の影に1pxの枠を重ねると輪郭がはっきりします。

.input-well {
  background: #eef2f7;
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.25),
    inset 0 0 0 1px #c8d2de;
}

inset は box-shadow だけの機能です。text-shadow と drop-shadow() には内側の影がありません。文字の内側をくぼませたい場合は、背景を切り抜く別の手法が必要になります。

チェックボックスやラジオボタンを自作するときにも、この内側の影がよく登場します。作り方はチェックボックス/ラジオボタンをCSSでデザインする方法にまとめています。

下だけに影をつける

結論:垂直方向のオフセットでいったん下にずらし、広がり(spread)をマイナスにして左右を削ります。

/* 下だけにふわっと影を出す */
.shadow-bottom {
  box-shadow: 0 10px 10px -8px rgba(0, 0, 0, 0.6);
}

数値の意味はこうです。10px下にずらし、10pxぼかし、-8pxで影全体を縮めています。縮めることで左右と上にはみ出していた影が消え、下だけが残ります。

上だけに出したい場合は、垂直方向のオフセットをマイナスにします。

.shadow-top {
  box-shadow: 0 -10px 10px -8px rgba(0, 0, 0, 0.6);
}

四辺に均等に出したい場合は、オフセットを両方0にします。

.shadow-all {
  box-shadow: 0 0 18px rgba(0, 0, 0, 0.45);
}

3枚重ねて自然な影にする

結論:距離と濃さの違う影を3つ重ねると、1つで作るより自然に見えます。

.card {
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.16),
    0 4px 8px rgba(0, 0, 0, 0.14),
    0 12px 24px rgba(0, 0, 0, 0.12);
}

近くて濃い影・中くらいの影・遠くて薄い影、という3段構成です。実際の光と影は距離によってぼけ方が変わるので、1枚だけより馴染みます。カードやモーダルのように「浮かせたい」要素に向いています。

枠線の代わりに使う

結論:ぼかし0・広がりだけを指定すると、線が引けます。borderと違ってレイアウトの大きさを変えないのが利点です。

/* 1pxの線+その外側に薄いリング(フォーカス表示などに) */
.ring {
  box-shadow:
    0 0 0 1px #9fb4cc,
    0 0 0 5px rgba(74, 122, 181, 0.35);
}

borderを足すと要素のサイズが変わって周りがずれますが、box-shadowは描画されるだけなのでずれません。フォーカス時だけリングを出す、といった使い方に向いています。

基本2:text-shadowを実装する方法

文字そのものに影を付けるプロパティがtext-shadowです。box-shadowと違い、insetと広がり(spread)は使えません。

▼text-shadowの値の並び順

text-shadow: 水平方向のオフセット 垂直方向のオフセット [ぼかし半径] [色];
.shadow-text {
  text-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3);
}

文字に影をつける

See the Pen
shadow-text
by りん@エンジニア (@rinblog0408)
on CodePen.

見出しでよく使う「ズラし影」も1行です。ぼかしを0にして、色をはっきりした色にすると効果が出ます。

.shadow {
  text-shadow: 4px 4px 0 #c3a400;
}

文字を縁取りする

結論:ぼかし0の影を8方向に重ねると、文字の縁取りになります。写真の上に白文字を置くときに読みやすくなります。

.outlined {
  color: #fff;
  text-shadow:
     2px 0 0 #000, -2px 0 0 #000,
     0 2px 0 #000,  0 -2px 0 #000,
     1.5px 1.5px 0 #000, -1.5px 1.5px 0 #000,
     1.5px -1.5px 0 #000, -1.5px -1.5px 0 #000;
}

上下左右の4方向だけだと、斜めの部分に隙間が出ます。斜め4方向も足して8つ重ねると、太さが均一に見えます。

同じことは -webkit-text-stroke でも書けます。

.outlined-stroke {
  color: #fff;
  -webkit-text-stroke: 2px #000;
  paint-order: stroke fill; /* 線を文字の下に描いて、細らせない */
}

paint-order: stroke fill を付けないと、線が文字の内側にも食い込みます。同じ文字で白い部分の面積を数えたところ、付けない場合は 2,411 画素、付けた場合は 8,972 画素でした。3倍以上細って見えるということです。

縁取りだけなら、重ねる数が少なく済むこちらのほうが管理しやすいです。Chrome 154・Firefox 157・WebKit 27.2 のいずれでも同じように描画できました。

文字を発光させる

結論:オフセットを0にして、ぼかしだけを効かせた影を2つ重ねると、光っているように見えます。

.glow {
  color: #fff;
  text-shadow:
    0 0 10px #ffe66b,
    0 0 20px #ffb300;
}

内側に明るい色、外側に濃い色を置くのがコツです。暗い背景の上でないと効果が分かりにくいので、使う場所は選びます。

スポンサーリンク

応用1:複数のshadowをカンマで重ねる

影はカンマ区切りで何個でも重ねられます。先に書いたものほど手前に描画されます。

.shadow-box {
  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.3), -5px -5px 5px rgba(0, 0, 0, 0.3);
}

この書き方はtext-shadowでも同じです。明るい影と暗い影を左上・右下に振り分けて立体感を出す手法もこの応用で、ニューモーフィズムを使ったUI/UXデザインの魅力と実装例で扱っているデザインはこの重ね方が中心になっています。

影の色はcolor-mix()でその場で作ることもできます。3つのブラウザとも、影の色として問題なく描画されました。

.mixed {
  box-shadow: 0 8px 12px color-mix(in oklab, #000 45%, transparent);
}

不透明度つきの色をいちいちrgba()で書かずに済みます。色関数の書き方はCSS color()関数の使い方と実用例にまとめています。

応用2:blurとspreadの違いを理解する

blur(ぼかし半径)は影の輪郭をぼかす値、spread(広がり)は影のサイズ自体を変える値です。両方とも3番目・4番目に書きますが、効果はまったく別物です。

/* 基本:ぼかしのみ */
.shadow-box {
  box-shadow: 0 5px 5px rgba(0, 0, 0, 0.3);
}

/* blurを大きくする:輪郭がぼやけて広がる */
.shadow-box.blur {
  box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);
}

/* spreadを足す:影のサイズそのものが大きくなる */
.shadow-box.spread {
  box-shadow: 0 5px 5px 8px rgba(0, 0, 0, 0.3);
}

/* spreadを負にする:影が縮んで細く見える */
.shadow-box.shrink {
  box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.3);
}

実務でよく使うのは負のspreadです。ぼかしを強めにしつつspreadをマイナスにすると、影が要素の下側だけに集まり、浮いているように見せられます。

スポンサーリンク

応用3:drop-shadowで形に沿った影をつける

See the Pen
filter:drop-shadow
by りん@エンジニア (@rinblog0408)
on CodePen.

透過PNGのアイコンやclip-pathで切り抜いた要素に影をつけるならfilter: drop-shadow()です。box-shadowが要素の四角いボックスに影を落とすのに対し、drop-shadow()は画像の不透明な部分(アルファチャンネル)の形に沿って影を落とします。

.shadow {
  filter: drop-shadow(10px 10px 0 #c3a400);
}

星形の透過PNGで並べて試したところ、drop-shadow()は星の形の影が出たのに対し、box-shadowは星ではなく四角いボックスの影が出ました。「影がおかしい」と悩む原因のほとんどがこれです。

drop-shadowで気をつける3点

1つ目。drop-shadow()にはinsetとspreadがありません。書けるのはオフセット2つ、ぼかし半径、色だけです。

2つ目。ぼかし半径の解釈がbox-shadowと違います。drop-shadow()の3つ目の値はガウスぼかしの標準偏差として扱われるため、同じ数値でもぼけ方が強く出ます。どれくらい違うのか、同じ正方形に同じ数値を与えて、影が消えるまでの距離を測りました。

▼同じ数値を指定したときに影が届く距離(Chrome 154で計測)

指定した値 box-shadow drop-shadow()
5px 4px 9px
10px 9px 19px
20px 19px 37px
40px 38px 67px

おおよそ2倍です。box-shadowの値をそのままdrop-shadow()に移すと、想定の倍ぼけます。置き換えるときは半分くらいから試してください。

3つ目。複数指定の書き方が違います。drop-shadow(...) drop-shadow(...)とスペース区切りで並べます。カンマ区切りではありません。

/* 発光させてから、下に影を落とす */
.icon {
  filter: drop-shadow(0 0 6px #e8551f) drop-shadow(0 6px 4px rgba(0, 0, 0, 0.4));
}

clip-pathと同じ要素に書くと影が消える

結論:clip-pathとfilter: drop-shadow()を同じ要素に書くと、影ごと切り取られて消えます。影を出したいなら、親要素にfilterを書いてください。

/* これは影が出ない(影ごと切り取られる) */
.triangle {
  background: #4a7ab5;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  filter: drop-shadow(8px 8px 3px rgba(0, 0, 0, 0.6));
}
<div class="triangle-wrap">
  <div class="triangle"></div>
</div>
/* 親に filter を書くと影が出る */
.triangle-wrap {
  filter: drop-shadow(8px 8px 3px rgba(0, 0, 0, 0.6));
}

.triangle {
  background: #4a7ab5;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

filterで影を描いたあとにclip-pathで切り取る順序になるため、同じ要素に書くと影の部分が切り落とされます。Chrome・Firefox・WebKitのいずれでも同じ結果でした。

box-shadowと重ねると、影ごと複製される

結論:同じ要素にbox-shadowとdrop-shadow()を書くと、drop-shadow()は「要素+box-shadowの影」をひとかたまりの形として複製します。

.double {
  background: #4a7ab5;
  box-shadow: 26px 26px 0 #cc4444;                 /* 赤い影 */
  filter: drop-shadow(-30px 60px 0 #2aa84a);       /* 緑の影 */
}

これを実際に表示すると、緑の影は四角1つぶんではなく、元の要素と赤い影を合わせた階段状の形になります。filterは要素が描き終わった結果に対してかかるためです。

意図していないと事故になります。両方を重ねたいときは、box-shadowを内側の要素に、drop-shadow()を外側の要素に分けてください。

どれを使うかの判断フロー

結論:次の3つを順番に当てはめれば決まります。

  • 1. 影を落としたいのは文字か? → はい:text-shadow
  • 2. 要素の形(四角・角丸)どおりの影でよいか? → はい:box-shadow
  • 3. 切り抜かれた形に沿わせたいか? → はい:filter: drop-shadow()

判断に迷いやすいのは2と3の境目です。背景が透明な画像(透過PNG・SVG)や、clip-path・border-radius: 50%以外の変形をしている要素は3です。それ以外は2で足ります。

もう1つの軸として、重なり順に影響させたくないならbox-shadowという選び方もあります。filterを書いた要素は新しいスタッキングコンテキストを作るので、その中の子要素は、どれだけz-indexを大きくしても親の外の要素より手前に出られなくなります。

/* この filter を足した瞬間、.child は .sibling の後ろに回る */
.parent {
  position: absolute;
  filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.4));
}

.parent .child {
  position: absolute;
  z-index: 9999; /* それでも前に出られない */
}

.sibling {
  position: absolute; /* .parent より後ろに書かれた要素 */
}

同じ構造でfilterだけを外すと、.childは.siblingの手前に戻りました。ドロップダウンやツールチップを持つ要素にfilterを足すと、急に隠れるようになるのはこれが原因です。

なお、影を作るジェネレーターを使う場合も、出てくるのは同じbox-shadowの値です。見るべきは4つの数値(右・下・ぼかし・広がり)と色の不透明度だけなので、出力をそのまま貼る前に、この記事の表と見比べて意味を確認してください。

3つのshadowはどう使い分けるか

「影をつけたい対象が、四角い箱か・文字か・切り抜かれた形か」で選べば迷いません。

▼3つのshadowの比較

項目 box-shadow text-shadow drop-shadow()
影の形 要素のボックス 文字の形 不透明部分の形
ぼかし半径 ◯ ◯ ◯(同じ数値で約2倍ぼける)
広がり(spread) ◯ × ×
inset(内側の影) ◯ × ×
複数指定 カンマ区切り カンマ区切り スペース区切り
主な用途 カード・ボタン・入力欄 見出し・ロゴ文字 透過PNG・アイコン・切り抜き

実装では、カードやボタンはbox-shadow、キャッチコピーはtext-shadow、ロゴやイラストはdrop-shadow()という振り分けでほとんど足ります。BootstrapやTailwindのようなフレームワークにも影のユーティリティが用意されているので、自前で書くか既製のクラスを使うかはCSSでオススメのフレームワークと実装例【Bootstrap/Tailwind】も見ながら決めてください。

暗い背景では影がほとんど見えない

結論:黒い影は暗い背景の上では見えません。ダークモードで要素を浮かせたいなら、影ではなく1pxの明るい線を重ねます。

/* 暗い背景で輪郭を出す:薄い明線+影 */
.card-dark {
  background: #2a3340;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.14),
    0 8px 16px rgba(0, 0, 0, 0.6);
}

暗い背景に黒い影だけを置いて撮り比べたところ、影はほとんど判別できませんでした。明るい背景と同じ影の値をダークモードにそのまま流用すると、浮いて見えなくなります。配色を切り替えるときは、影の値も一緒に見直してください。

まとめ

CSSで影をつける3つの方法をまとめます。

  • 文字ならtext-shadow、四角い要素ならbox-shadow、切り抜かれた形ならdrop-shadow()
  • 内側の影(inset)と広がり(spread)はbox-shadowだけの機能
  • 下だけに出したいときは、下にずらしてspreadをマイナスにする
  • drop-shadow()のぼかしは同じ数値で約2倍ぼける
  • clip-pathと同じ要素にfilterを書くと影が消える。親に書く
  • 暗い背景では影が見えないので、1pxの明線を足す

▼HTML/CSS/JavaScriptの学習本を探している方はこちら

✅ 2023年版 Webコーディングにオススメの学習本【HTML/CSS/JavaScript】