デモで学ぶ CSS box-shadow 実践ガイド
box-shadow の4つの値(X・Y・ぼかし・広がり)と inset、さらに drop-shadow / text-shadow との違いまで、ボタン操作で見比べながら確認できます。すぐに使えるHTML・CSSのコードをコピーできます。
HTML・CSS・JSコードプレビューツール にて実装確認ができます。
① ぼかし(blur-radius)— 影のやわらかさ
現在: box-shadow: 0 8px 10px rgba(0, 0, 0, 0.35)
<img src="画像のパス" alt="説明" class="shadow-img">
.shadow-img {
display: block;
border-radius: 4px;
box-shadow: 0 8px 10px rgba(0, 0, 0, 0.35);
}
box-shadow は左から順に「横方向のずれ」「縦方向のずれ」「ぼかし量」「色」を指定します。3つ目のぼかし量(blur-radius)を大きくするほど影の縁がにじみ、やわらかい印象になります。0 を指定すると輪郭のはっきりした影になり、フラットデザインやレトロ表現で使われます。マイナス値は指定できません。
色は #000 のような不透明の黒ではなく、rgba(0, 0, 0, 0.35) のように透明度を落とした黒を使うのが基本です。下地の色が透けるため、背景が白でも色付きでもなじみます。またぼかし量に対してY方向のずれを小さめ(ぼかしの半分以下)にすると、真上から少し手前に光が当たった自然な影になります。
② オフセット(X / Y)— 影の向き
現在: box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.4)
<img src="画像のパス" alt="説明" class="shadow-img">
.shadow-img {
display: block;
border-radius: 4px;
box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.4);
}
1つ目の数値(X)がプラスなら右、マイナスなら左へ影がずれます。2つ目の数値(Y)がプラスなら下、マイナスなら上へずれます。両方を 0 にすると全方向へ均等に広がり、影というより「光っている」印象になります。ページ内で影の向きは統一するのが鉄則です。光源がひとつだけあると想定して、すべての要素で同じ方向に落とすと画面全体に統一感が出ます。
③ 広がり(spread-radius)— 影のサイズを調整する
現在: box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.35)
<img src="画像のパス" alt="説明" class="shadow-img">
.shadow-img {
display: block;
border-radius: 4px;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.35);
}
ぼかし量のあとに4つ目の数値を書くと、影そのものを拡大・縮小できます。プラスなら影が要素より大きく、マイナスなら小さくなります。よく使うのはマイナス指定で、たとえば box-shadow: 0 8px 16px -8px の形にすると、影が左右にはみ出さず真下だけに落ちるため、カードを横に並べたときに隣とにじみ合いません。
ずれもぼかしも 0 にして広がりだけを指定すると、box-shadow: 0 0 0 4px のように要素をぐるりと囲む「枠線」になります。border と違ってレイアウトの幅・高さに影響しないため、フォーカス時のリングやホバー時の強調に最適です。カンマ区切りで重ねれば、二重・三重の枠線も作れます。
④ inset — 内側に影を付ける
現在: box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.3)
<div class="inset-frame">
<img src="画像のパス" alt="説明">
</div>
.inset-frame {
position: relative;
display: inline-block;
border-radius: 4px;
}
.inset-frame img {
display: block;
border-radius: 4px;
}
.inset-frame::after {
content: '';
position: absolute;
inset: 0;
border-radius: 4px;
pointer-events: none;
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.3);
}
値の先頭に inset を付けると、影が要素の外側ではなく内側に落ちます。へこんだ入力欄、押し込まれたボタン、写真に落とす額縁のような陰影など、「奥まって見せたい」表現に使います。書ける値は外側の影とまったく同じで、inset 0 0 20px rgba(0, 0, 0, 0.3) のように X・Y・ぼかし・広がり・色をそのまま並べられます。
img タグに inset の box-shadow を書いても、影は画像に隠れて見えません。内側の影は要素の背景のすぐ上に描かれる決まりで、画像そのもの(置換コンテンツ)はさらにその上に描かれるためです。解決策は上のコードのように、画像を包む要素の ::after を透明な板として画像の上に重ね、その板に inset シャドウを持たせることです。position: absolute で重ねているので確実に画像より前面に描かれ、pointer-events: none を付けておけばクリックの邪魔もしません。
⑤ カンマ区切り — 影を重ねて立体的にする
現在: ふわっと浮く(影2枚)
<img src="画像のパス" alt="説明" class="shadow-img">
.shadow-img {
display: block;
border-radius: 4px;
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.08),
0 10px 40px rgba(0, 0, 0, 0.25);
}
先に書いた影ほど手前に描かれます。「小さくて濃い影」と「大きくて薄い影」を組み合わせると、接地感と浮遊感が同時に出て一気に自然になります(ふわっと浮く)。ぼかしを 0 にして少しずつずらせば紙を重ねたような表現に(積み重ね)、広がりだけを使って重ねれば太さの違う多重の枠線になります(二重の枠線)。色付きの影を重ねれば発光表現も作れます(ネオングロー)。
⑥ filter: drop-shadow() — 透過画像の形に沿った影
現在: filter: drop-shadow(0 8px 8px rgba(0, 0, 0, 0.5))
<div class="shadow-wrap">
<div class="star"></div>
</div>
.shadow-wrap {
display: inline-block;
line-height: 0;
filter: drop-shadow(0 8px 8px rgba(0, 0, 0, 0.5));
}
.star {
width: 150px;
height: 150px;
background: linear-gradient(135deg, #fbbf24, #f59e0b);
clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
box-shadow が影を落とすのは要素のボックス(border-radius を含む矩形)に対してです。そのため透過PNGやSVGのロゴ、切り抜き画像に box-shadow を付けても、絵柄を無視した四角い影が出てしまいます。上のデモで「box-shadow」を選ぶと、星の形とは関係のない四角い影が出ることが確認できます。
filter: drop-shadow() は要素の不透明な部分(アルファチャンネル)を見て影を作るため、切り抜かれた形そのものに沿った影になります。透過PNGやSVGなら img タグに filter: drop-shadow(0 8px 8px rgba(0, 0, 0, 0.5)); と書くだけです。書き方は box-shadow に似ていますが、広がり(4つ目の値)は指定できず、inset も使えません。ぼかしの数値も box-shadow より強くかかるため、同じ見た目にしたいときは半分程度が目安です。
⑦ text-shadow — 文字に影を付ける
Shadow Text
現在: text-shadow: 0 4px 8px rgba(0, 0, 0, 0.4)
<p class="shadow-text">Shadow Text</p>
.shadow-text {
font-size: 2.4rem;
font-weight: 800;
color: #1e293b;
line-height: 1.3;
margin: 0;
text-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}
文字に影を付けるプロパティです。box-shadow とほぼ同じ書き方ですが、広がり(spread)と inset は指定できず、値は3つ+色までです。カンマ区切りで重ねられる点は同じで、同じ色の影を何枚も重ねるとネオンのような発光表現になります。上下左右にずらした影を4枚重ねれば、文字の縁取り(フチ文字)の代わりにもなります。
装飾以外に、写真の上に載せた文字を読みやすくする用途でも重宝します。text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8) のような控えめな影を付けるだけで、背景が明るくても暗くても文字の輪郭が保たれます。ただし影を濃くしすぎると逆に文字がぼやけて読みにくくなるため、本文には強い影を使わないでください。
ぼかし量の大きい box-shadow は描画コストが高く、たくさんの要素に付けるとスクロールが重くなることがあります。特にホバー時に影を動かすアニメーションでは、box-shadow の数値そのものをアニメーションさせるのではなく、あらかじめ影を持たせた擬似要素の opacity を切り替える方法のほうが滑らかに動きます。また、親要素に overflow: hidden が付いていると、はみ出した影は切り取られて見えなくなります。影が表示されないときは、まず親要素の overflow を確認してください。
よくある質問
box-shadow の数値は何個書けばいいですか?
最短は box-shadow: 0 4px 8px #000; の「X・Y・ぼかし・色」の形です。数値は左から順に X(横のずれ)→ Y(縦のずれ)→ ぼかし → 広がり と決まっており、後ろから省略できます。box-shadow: 4px 4px #000 のように2つだけ書けば、ぼかしも広がりも 0 の輪郭がはっきりした影になります。色は最初か最後のどちらに書いても構いませんが、最後に書くのが一般的です。
inset を付けたのに影が見えません。
img タグに直接指定していませんか。内側の影は要素の背景のすぐ上に描かれますが、画像そのものはさらに上に描かれるため、影が完全に隠れてしまいます。画像を div で包み、その ::after を画像の上に重ねて inset シャドウを持たせるのが確実な方法です。④のデモのコピペ用コードがそのまま使えます。input や div など通常の要素であれば、直接 inset を指定して問題ありません。
影が途中で切れてしまいます。
影を付けた要素の親側に overflow: hidden が付いている可能性が高いです。box-shadow は要素の外側にはみ出して描かれるため、親が切り取り設定になっているとその部分が消えます。親の overflow を visible に戻すか、影を付ける対象を親要素のほうに変更してください。スライダーやカルーセルの中でカードに影を付けたときに、よく起きるトラブルです。
box-shadow と filter: drop-shadow() はどう使い分けますか?
四角いカード・ボタン・入力欄など、要素の形がそのまま見た目になるものは box-shadow を使います。透過PNGのロゴ、SVGアイコン、切り抜き写真など「絵柄の形」に沿った影がほしいときだけ filter: drop-shadow() を使ってください。drop-shadow は広がり(spread)と inset が使えず、描画コストも高めなので、常用するものではありません。実際の見え方は⑥のデモで切り替えて比べられます。
影の色を省略するとどうなりますか?
色を書かなかった場合、影はその要素の color の値(currentColor)で描かれます。文字色が黒なら黒い影になりますが、文字色を変えた瞬間に影の色も一緒に変わってしまうため、意図しない見た目になりがちです。色は必ず明示的に書くことをおすすめします。逆にこの仕様を利用して、ボタンの文字色に連動した影をあえて作ることもできます。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

