WithCodeMedia-1-pc
previous arrowprevious arrow
next arrownext arrow

WithCodeMedia-1-sp
previous arrowprevious arrow
next arrownext arrow

【2026年版】CSS box-shadowの使い方完全ガイド|影の付け方をコピペで解説

CSSで要素に影をつけたいけれど、うまく表示されない。影の値の意味がよくわからない。書いてみたけど何も変わらない気がする。そんな悩みを抱えているWeb制作初心者の方は多いのではないでしょうか。box-shadowプロパティは一見シンプルですが、値が5つ並ぶため「どれが何を意味するのか」が直感的に分かりづらく、コピペしても意図通りに動かないケースが頻発するCSSプロパティのひとつです。特に、影の値を変えても見た目が変わらないときは焦りますよね。原因は案外シンプルなことが多いのですが、それを知らなければ何時間もハマることになります。

この記事はCSS初学者〜中級者のWeb制作者に向けて書いています。基本構文の読み方から、内側の影(inset)・複数の影の重ね方・ふんわりした影のデザイン実例、さらにtext-shadowとの違いや「影が表示されない原因と対処法」まで、ひとつの記事で網羅的に解説します。コードはすべてコピペで使える形で掲載しているので、手元のプロジェクトにそのまま持っていくことができます。一度仕組みを理解してしまえば、デザインの幅がぐっと広がります。

最後まで読めば、box-shadowを自在にコントロールできるようになり、カードUIやボタンに立体感・奥行き感を与えるデザイン表現が身につきます。コードを1行ずつ丁寧に解説しているので、プログラミングに不慣れな方も安心して読み進めてください。それでは順番に見ていきましょう。

先に、この記事の結論をまとめます。

  • box-shadowは「水平オフセット・垂直オフセット・ぼかし半径・広がり半径・色」の5値で指定し、カンマ区切りで複数の影を重ねられる
  • insetキーワードを先頭に付けると影が要素の内側に入り込み、「へこんだ」表現が作れる
  • 複数の影を組み合わせると単体では出せないリアルな立体感・ネオモーフィズム表現が可能になる
  • text-shadowは文字専用・box-shadowは要素ボックス専用と役割が明確に分かれている
  • 影が表示されない原因はoverflow:hidden・z-index・clip-path・透明度の設定ミスなど複数あり、順番に確認すれば必ず解決できる
目次

box-shadowの基本構文|5つの値を完全理解する

box-shadowの基本構文は次の通りです。値の並び順を正しく覚えることが、すべての出発点になります。慣れないうちは「横・縦・ぼかし・広がり・色」という順番で覚えると間違えにくくなります。

selector {
  box-shadow: [水平オフセット] [垂直オフセット] [ぼかし半径] [広がり半径] [色];
}

具体的なコードで確認しましょう。

.card {
  box-shadow: 4px 8px 16px 0px rgba(0, 0, 0, 0.2);
}

このコードが意味するのは次の通りです。各値の役割をひとつずつ確認していきましょう。

この例意味
水平オフセット(offset-x)4px影を右方向へ4pxずらす(マイナスなら左)
垂直オフセット(offset-y)8px影を下方向へ8pxずらす(マイナスなら上)
ぼかし半径(blur-radius)16px影のエッジをぼかす半径。0だとくっきり
広がり半径(spread-radius)0px影のサイズを拡大・縮小する。省略可(省略時は0)
色(color)rgba(0,0,0,0.2)影の色。rgba・hex・hslなどすべて使える

なお、広がり半径(spread-radius)は省略できます。省略した場合は 0px として扱われます。また、色も省略でき、その場合はテキストカラー(color プロパティの値)が使われます。実務では必ず色を明示するのが無難です。

水平・垂直オフセットの符号で方向が決まる

offset-x が正の値なら影は右、負なら左に動きます。offset-y が正なら下、負なら上です。どちらも 0 にすると影は要素の真下に落ち、全方向均等な影になります。実際の光源の位置をイメージしながら値を設定すると、自然なデザインになります。例えば「左上から光が当たっている」という設定をするなら、offset-x と offset-y をともに正の値にします(光源が左上なら影は右下に落ちる)。

/* 右下に落ちる基本的な影 */
.shadow-right-bottom {
  box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.25);
}

/* 真下に落ちる均等な影(カードUI向け) */
.shadow-center {
  box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.15);
}

/* 上方向に落ちる影(フッター付近の要素に使う) */
.shadow-top {
  box-shadow: 0px -4px 10px rgba(0, 0, 0, 0.2);
}

/* 左右対称の影(ポップアップモーダルなど) */
.shadow-symmetric {
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.15);
}

Web制作の現場では、offset-x を 0 にして offset-y だけに値を入れるパターン(真下落ちの影)が最もよく使われます。カードやボタンなど、地面から浮いているような表現に自然にマッチするからです。

ぼかし半径(blur-radius)の効果

blur-radius は 0 以上の値しか指定できません(マイナスにするとエラーになります)。0 にすると影の縁がシャープになり、くっきりとした輪郭の影になります。値を大きくするほどグラデーションが広がり、ふんわりした柔らかい影になります。

重要なのは「ぼかし半径を大きくしても影の面積は広がらない」という点です。影のサイズを変えたいときは spread-radius を使います。blur-radius はあくまで「エッジのやわらかさ」だけを制御します。この2つを混同しているケースが多いので注意しましょう。

/* くっきりした影(blur=0)。印刷物のような硬い表現 */
.sharp-shadow {
  box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.4);
}

/* やや柔らかい影。一般的なカードUIに向く */
.soft-shadow {
  box-shadow: 4px 4px 12px rgba(0, 0, 0, 0.25);
}

/* 非常にふんわりした影。モダンなUIデザインに多い */
.fluffy-shadow {
  box-shadow: 0px 8px 40px rgba(0, 0, 0, 0.12);
}

/* ぼかしが大きいと影が薄く広がる。透明度を少し上げると◎ */
.wide-blur {
  box-shadow: 0px 4px 60px rgba(0, 0, 0, 0.18);
}

広がり半径(spread-radius)でサイズを調整する

spread-radius は影全体を均等に拡大・縮小します。正の値で影が大きくなり、負の値で小さくなります。この値を -1〜-4px 程度のマイナスにしてぼかし半径と組み合わせると、影が要素のすぐ下から自然に広がるように見え、より写実的な影の表現ができます。デザインツール(FigmaやAdobe XDなど)で出力したCSS値にマイナスのspread-radiusが含まれているのを見たことがある方も多いでしょう。

/* 広がりを大きくしてフチ全体に影を出す */
.wide-shadow {
  box-shadow: 0px 4px 16px 8px rgba(0, 0, 0, 0.15);
}

/* spreadをマイナスにしてよりリアルな影に */
.realistic-shadow {
  box-shadow: 0px 8px 24px -4px rgba(0, 0, 0, 0.2);
}

/* borderの代わりにbox-shadowを使う(レイアウトに影響しない) */
.border-like {
  box-shadow: 0px 0px 0px 2px #d16176;
}

/* ホバー時にborderが追加されてもレイアウトがずれない技 */
.btn-no-layout-shift {
  box-shadow: 0px 0px 0px 0px transparent;
  transition: box-shadow 0.2s ease;
}
.btn-no-layout-shift:hover {
  box-shadow: 0px 0px 0px 2px #d16176;
}

最後の2例のように、spread-radius だけ使って offset を 0・blur を 0 にすると、border のような枠線代わりに使うことができます。border とは異なり、box-shadow は要素のサイズに影響しないため、ホバー時のボーダー追加によるレイアウトズレを防ぐテクニックとしてもよく使われます。レイアウトが崩れる問題に悩んでいた方には特に有用です。

box-shadowで使える色の指定方法

box-shadow の色は CSS で使えるほぼすべての色記法が使えます。一番よく使うのは rgba() で、第4引数(アルファ値)で透明度を調整できるため、背景色に溶け込む自然な影が作れます。hex カラーは透明度が指定できないため、影がくっきり出すぎることがあります。

記法特徴
rgba()rgba(0, 0, 0, 0.2)透明度指定可。最もよく使う
hsla()hsla(0, 0%, 0%, 0.2)色相・彩度・明度で指定。感覚的に調整しやすい
hex(6桁)#333333透明度なし。影がくっきり出る
hex(8桁)#33333333最後の2桁が透明度。比較的新しい記法
キーワードtransparent / black影を消す(transition用)などに使う

内側に影をつける|insetキーワードの使い方

box-shadow の先頭に inset を加えると、影が要素の外側ではなく内側に描画されます。これにより、要素が「へこんでいる」ような表現や、入力フォームのフォーカス時に内側から光るエフェクトが作れます。inset は値の最初に書く必要があります。途中に書いてもエラーにはなりませんが、仕様上は先頭に置くのが正しい記述です。

/* 基本のinset(内側の影) */
.inset-basic {
  box-shadow: inset 0px 4px 8px rgba(0, 0, 0, 0.2);
}

/* 上からへこんでいるような表現 */
.inset-pressed {
  box-shadow: inset 0px 6px 12px rgba(0, 0, 0, 0.25);
}

/* 下から光が当たっているような表現(白い内側の光) */
.inset-light {
  box-shadow: inset 0px -4px 8px rgba(255, 255, 255, 0.5);
}

/* 全方向から内側に影(くぼんだコンテナ) */
.inset-all {
  box-shadow: inset 0px 0px 16px rgba(0, 0, 0, 0.15);
}

inset の offset-x・offset-y の方向は通常の box-shadow と同じ考え方です。ただし影が内側に反転するため、offset-y が正なら内側の上部に影が落ちます(外側の場合は下部に影が落ちる)。最初は混乱しやすいので、実際にブラウザの開発ツールで値を変えながら感覚をつかむことをおすすめします。

フォームの入力欄にinsetを使う

テキストボックスやテキストエリアにinsetを使うと、入力欄が実際にへこんでいるように見えるUIが実現できます。ユーザーが「ここに文字が入力できる」と直感的に分かるデザインになります。フォーカス時に色を変えると、現在どの入力欄にカーソルがあるかを視覚的に示すこともでき、アクセシビリティの向上にもつながります。

input[type="text"],
input[type="email"],
textarea {
  border: 1px solid #ccc;
  border-radius: 6px;
  padding: 10px 14px;
  font-size: 16px;
  box-shadow: inset 0px 2px 6px rgba(0, 0, 0, 0.08);
  outline: none;
  transition: box-shadow 0.3s ease, border-color 0.3s ease;
}

input[type="text"]:focus,
input[type="email"]:focus,
textarea:focus {
  box-shadow:
    inset 0px 2px 6px rgba(0, 0, 0, 0.08),
    0px 0px 0px 3px rgba(209, 97, 118, 0.3);
  border-color: #d16176;
}

ボタンの押し込みエフェクトにinsetを使う

ボタンのactive状態にinsetを組み合わせると、クリック時に「押し込んだ」感触を視覚的に表現できます。物理的なボタンを押した感覚に近いUX体験を提供でき、ユーザーが「クリックできた」と確認しやすくなります。offset-yを正にして上から影を落とすのがポイントです。さらに transform: translateY() で要素自体を少し下に動かすことでリアリティが増します。

.btn-press {
  display: inline-block;
  padding: 12px 28px;
  background: #d16176;
  color: #fff;
  font-weight: bold;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.25);
  transition: box-shadow 0.1s ease, transform 0.1s ease;
}

.btn-press:hover {
  box-shadow: 0px 6px 14px rgba(0, 0, 0, 0.3);
}

.btn-press:active {
  box-shadow: inset 0px 3px 6px rgba(0, 0, 0, 0.3);
  transform: translateY(2px);
}

insetを使ったくぼみカードデザイン

コンテンツを囲むコンテナに内側の影を付けると、背景に埋まったような「トレイ」や「くぼんだパネル」の表現ができます。ダッシュボードUIやサイドパネルによく使われます。

/* くぼんだトレイ型コンテナ */
.tray {
  background: #f5f5f5;
  border-radius: 12px;
  padding: 24px;
  box-shadow:
    inset 0px 2px 8px rgba(0, 0, 0, 0.12),
    inset 0px -1px 4px rgba(255, 255, 255, 0.6);
}

/* ダークモード向けのくぼみ */
.tray-dark {
  background: #1a1a2e;
  border-radius: 12px;
  padding: 24px;
  box-shadow:
    inset 0px 2px 8px rgba(0, 0, 0, 0.5),
    inset 0px -1px 4px rgba(255, 255, 255, 0.05);
}

複数の影を重ねてリアルな立体感を出す

box-shadow はカンマ区切りで複数の影を同時に指定できます。これを活用すると、単一の影では表現できないリアルな立体感・質感を生み出せます。影は左に書いたものほど手前に描画されます。実際のPhotoshopのレイヤーシャドウ機能と同じような考え方です。なぜ複数の影を重ねるのかというと、現実世界では光が散乱するため「ひとつの均一な影」は生じないからです。近距離では濃くシャープな影が、遠距離では薄く広い影が重なっています。この現象をCSSでシミュレートするのが「複数シャドウ」の発想です。

/* 2層の影で立体感を出す(よく使われるパターン) */
.card-multi {
  box-shadow:
    0px 2px 4px rgba(0, 0, 0, 0.12),
    0px 8px 24px rgba(0, 0, 0, 0.1);
}

/* 3層の影でさらにリッチな表現 */
.card-rich {
  box-shadow:
    0px 1px 2px rgba(0, 0, 0, 0.08),
    0px 4px 8px rgba(0, 0, 0, 0.1),
    0px 16px 32px rgba(0, 0, 0, 0.08);
}

/* Material Design風の影(Googleが使うパターン) */
.card-material {
  box-shadow:
    0px 3px 1px -2px rgba(0, 0, 0, 0.2),
    0px 2px 2px 0px rgba(0, 0, 0, 0.14),
    0px 1px 5px 0px rgba(0, 0, 0, 0.12);
}

/* ホバー時に影が強くなるMaterial Design elevation */
.card-material:hover {
  box-shadow:
    0px 5px 5px -3px rgba(0, 0, 0, 0.2),
    0px 8px 10px 1px rgba(0, 0, 0, 0.14),
    0px 3px 14px 2px rgba(0, 0, 0, 0.12);
  transition: box-shadow 0.3s ease;
}

ネオモーフィズムデザインを複数shadowで実現する

ネオモーフィズム(Neumorphism)は2020年前後に流行したデザインスタイルで、要素が背景と同じ素材でできているように見える表現です。明るい影と暗い影を同時に使うのが特徴で、box-shadowの複数指定なしには成立しません。なお、コントラスト比が低くなりがちなため、アクセシビリティへの配慮が必要です。

/* ネオモーフィズム・浮き出ている状態 */
.neumorphism {
  background: #f0f0f0;
  border-radius: 16px;
  padding: 24px;
  box-shadow:
    6px 6px 12px rgba(0, 0, 0, 0.15),
    -6px -6px 12px rgba(255, 255, 255, 0.8);
}

/* ネオモーフィズム・凹んでいる状態 */
.neumorphism-inset {
  background: #f0f0f0;
  border-radius: 16px;
  padding: 24px;
  box-shadow:
    inset 4px 4px 8px rgba(0, 0, 0, 0.15),
    inset -4px -4px 8px rgba(255, 255, 255, 0.8);
}

/* ネオモーフィズム・ダークモード版 */
.neumorphism-dark {
  background: #1a1a2e;
  border-radius: 16px;
  padding: 24px;
  box-shadow:
    6px 6px 12px rgba(0, 0, 0, 0.5),
    -6px -6px 12px rgba(255, 255, 255, 0.05);
}

カラーの影を複数重ねてグロー効果を作る

影の色は必ずしも黒系にする必要はありません。ブランドカラーやビビッドな色を使った影は、現代的なデザイントレンドのひとつです。複数のカラー影を組み合わせると、グロー(光彩)効果も作れます。ゲームUI・クリエイティブ系サイト・ダークモードのUIで特に効果的です。

/* ピンク系グロー */
.glow-pink {
  box-shadow:
    0px 0px 8px rgba(209, 97, 118, 0.4),
    0px 0px 24px rgba(209, 97, 118, 0.2),
    0px 0px 48px rgba(209, 97, 118, 0.1);
}

/* マルチカラーの影(ポップなデザイン向け) */
.multi-color-shadow {
  box-shadow:
    -6px 6px 0px #EFBDB7,
     6px -6px 0px #d16176;
}

/* Stripe風の深みある青い影 */
.card-stripe {
  box-shadow:
    0px 4px 6px rgba(50, 50, 93, 0.11),
    0px 1px 3px rgba(0, 0, 0, 0.08);
}

/* ゴールドのグロー(プレミアム感) */
.gold-glow {
  box-shadow:
    0px 0px 8px rgba(255, 193, 7, 0.5),
    0px 0px 24px rgba(255, 193, 7, 0.25),
    0px 4px 16px rgba(0, 0, 0, 0.2);
}

外側と内側の影を同時に指定する

inset の影と通常の外側の影は、カンマで区切ることで同時に適用できます。ホバー時のエフェクトとして外側の影を追加しながら内側の光を入れる、といった複合的な表現が可能です。ガラス質感(glassmorphism)の表現にも活用されます。

.card-combined {
  box-shadow:
    0px 4px 16px rgba(0, 0, 0, 0.12),          /* 外側の影 */
    inset 0px 1px 2px rgba(255, 255, 255, 0.6); /* 内側の上部に光 */
}

.card-combined:hover {
  box-shadow:
    0px 12px 32px rgba(0, 0, 0, 0.18),
    inset 0px 1px 2px rgba(255, 255, 255, 0.6);
  transition: box-shadow 0.3s ease;
}

/* ガラス風カード(glassmorphism) */
.glass-card {
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(12px);
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  box-shadow:
    0px 8px 32px rgba(0, 0, 0, 0.2),
    inset 0px 1px 0px rgba(255, 255, 255, 0.4);
}

ふんわり浮き上がる影の実例集|カード・ボタンのコピペコード

実際の制作現場でよく使われる影パターンを、カードとボタンに分けてまとめます。パラメータの意味が分かれば、色や数値を自分のデザインに合わせて変えるだけで使えます。どれもすぐに使えるコピペ用コードとして掲載しています。背景色・要素の色・影の色の組み合わせを変えるだけで、自分のブランドに合ったデザインが作れます。

カードUIの影パターン5選

カードコンポーネントに使う影は、ページの背景色と要素の背景色の関係によって見え方が大きく変わります。白背景の場合は薄い黒の rgba が最も自然な印象になります。影のパラメータはデザインの雰囲気に合わせて選びましょう。

/* ── パターン1: 軽くて上品なカード ── */
.card-light {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.08);
}

/* ── パターン2: ふんわり浮いているカード ── */
.card-float {
  background: #fff;
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0px 8px 32px rgba(0, 0, 0, 0.1);
}

/* ── パターン3: ホバーで浮き上がるカード ── */
.card-hover {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.08);
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.card-hover:hover {
  box-shadow: 0px 12px 32px rgba(0, 0, 0, 0.15);
  transform: translateY(-4px);
}

/* ── パターン4: ブランドカラーの影がついたカード ── */
.card-brand {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  box-shadow:
    0px 4px 16px rgba(209, 97, 118, 0.2),
    0px 1px 4px rgba(209, 97, 118, 0.1);
}

/* ── パターン5: ダークカード ── */
.card-dark {
  background: #2c2c3e;
  border-radius: 16px;
  padding: 24px;
  color: #fff;
  box-shadow:
    0px 8px 24px rgba(0, 0, 0, 0.4),
    0px 2px 6px rgba(0, 0, 0, 0.3);
}

ボタンの影パターン4選

ボタンに影をつけると、クリックできる要素であることをユーザーに視覚的に伝えやすくなります。active 状態で影を消したり縮小すると、押し込み感が生まれてUXが向上します。transition を忘れずに指定しましょう。

/* ── パターン1: シンプルなシャドウボタン ── */
.btn-simple {
  display: inline-block;
  padding: 12px 32px;
  background: #d16176;
  color: #fff;
  font-weight: bold;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  box-shadow: 0px 4px 12px rgba(209, 97, 118, 0.45);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.btn-simple:hover {
  box-shadow: 0px 6px 20px rgba(209, 97, 118, 0.55);
  transform: translateY(-2px);
}
.btn-simple:active {
  box-shadow: 0px 2px 6px rgba(209, 97, 118, 0.3);
  transform: translateY(0);
}

/* ── パターン2: フラットな3D風ボタン ── */
.btn-flat-3d {
  display: inline-block;
  padding: 12px 32px;
  background: #d16176;
  color: #fff;
  font-weight: bold;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  box-shadow: 0px 6px 0px #9e3950;
  transition: box-shadow 0.1s ease, transform 0.1s ease;
}
.btn-flat-3d:active {
  box-shadow: 0px 2px 0px #9e3950;
  transform: translateY(4px);
}

/* ── パターン3: グロー効果のあるネオン風ボタン ── */
.btn-glow {
  display: inline-block;
  padding: 12px 32px;
  background: #d16176;
  color: #fff;
  font-weight: bold;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  box-shadow:
    0px 0px 8px rgba(209, 97, 118, 0.5),
    0px 0px 24px rgba(209, 97, 118, 0.3);
  transition: box-shadow 0.3s ease;
}
.btn-glow:hover {
  box-shadow:
    0px 0px 12px rgba(209, 97, 118, 0.8),
    0px 0px 40px rgba(209, 97, 118, 0.4);
}

/* ── パターン4: シャドウなしアウトライン → ホバーでシャドウ出現 ── */
.btn-outline-shadow {
  display: inline-block;
  padding: 12px 32px;
  background: transparent;
  color: #d16176;
  font-weight: bold;
  border: 2px solid #d16176;
  border-radius: 8px;
  cursor: pointer;
  box-shadow: none;
  transition: box-shadow 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.btn-outline-shadow:hover {
  background: #d16176;
  color: #fff;
  box-shadow: 0px 4px 16px rgba(209, 97, 118, 0.4);
}

transitionと組み合わせて滑らかに変化させる

box-shadow は CSS transition でアニメーション可能です。hover や focus のタイミングで影を変える際は、必ず transition を親側(通常状態)のセレクタに書くのがポイントです。hover 側に書いてしまうと、hover を外したときにアニメーションせず、唐突に影が消えてしまいます。transition の timing-function は ease や cubic-bezier を使うと自然な動きになります。

.animated-card {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  /* transitionは通常状態のセレクタに書く */
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.08);
  transition:
    box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.animated-card:hover {
  box-shadow: 0px 16px 40px rgba(0, 0, 0, 0.16);
  transform: translateY(-6px);
}

text-shadow(文字の影)との違いと使い方

CSSには影に関するプロパティが2つあります。box-shadow と text-shadow です。名前が似ていますが、適用対象・値の構成・用途がまったく異なります。混同して使ってしまうと意図通りの結果が得られないため、違いをしっかり理解しておきましょう。

項目box-shadowtext-shadow
適用対象要素ボックス全体(div・section・buttonなど)テキスト文字だけ
insetキーワード使える使えない
広がり半径(spread)4番目の値として指定可なし(最大3値のみ)
複数指定カンマ区切りで可カンマ区切りで可
主な用途カード・ボタン・UIコンポーネント全般見出しの装飾・読みやすさの向上
パフォーマンスやや重い(repaint発生)同様にrepaint発生

text-shadowの基本構文

text-shadow は「水平オフセット・垂直オフセット・ぼかし半径・色」の3〜4値で指定します。box-shadow と違うのは、spread(広がり半径)が存在しない点です。また、inset も使えません。文字が読みやすくなるようにサポートする目的で使うのが基本であり、派手にしすぎると逆に読みにくくなるので注意が必要です。

/* 基本のtext-shadow */
.heading-shadow {
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

/* くっきりした文字の影 */
.heading-sharp {
  text-shadow: 3px 3px 0px rgba(0, 0, 0, 0.4);
}

/* 白い文字に黒の影で視認性を上げる(ヒーローセクションなど) */
.hero-text {
  color: #fff;
  text-shadow: 1px 1px 6px rgba(0, 0, 0, 0.6);
}

/* ぼかしを大きくしたやわらかい影 */
.heading-soft {
  text-shadow: 0px 4px 12px rgba(0, 0, 0, 0.2);
}

text-shadowを複数重ねて面白い表現をする

text-shadow も box-shadow と同様にカンマ区切りで複数指定できます。アウトライン(文字の縁取り)・3D文字・グロー効果などが作れます。border-strokeのような文字の縁取りは -webkit-text-stroke でも実現できますが、text-shadow の複数指定でも近い表現が可能です。

/* 四方にアウトラインを出す(縁取り文字) */
.text-outline {
  color: #fff;
  text-shadow:
    -1px -1px 0 #d16176,
     1px -1px 0 #d16176,
    -1px  1px 0 #d16176,
     1px  1px 0 #d16176;
}

/* 3D文字(段階的にずらして立体感を出す) */
.text-3d {
  color: #fff;
  text-shadow:
    1px 1px 0 #b04d62,
    2px 2px 0 #9e3950,
    3px 3px 0 #8c2a3e,
    4px 4px 0 #7a1b2c;
}

/* グロー文字(ダークモード・ゲームUI向け) */
.text-glow {
  color: #fff;
  text-shadow:
    0px 0px 8px rgba(209, 97, 118, 0.8),
    0px 0px 24px rgba(209, 97, 118, 0.5),
    0px 0px 48px rgba(209, 97, 118, 0.3);
}

/* 長い影(フラットデザインのアクセント) */
.text-long-shadow {
  color: #d16176;
  text-shadow:
    1px 1px 0 #EFBDB7,
    2px 2px 0 #EFBDB7,
    3px 3px 0 #EFBDB7,
    4px 4px 0 #EFBDB7,
    5px 5px 0 #EFBDB7;
}

box-shadowとtext-shadowを使い分ける判断基準

どちらを使うかの判断は明確です。カードやボタンなど「ボックス形状の要素全体」に影をつけたいなら box-shadow を使います。見出しや段落テキストなど「文字そのものに影をつけたい」場合は text-shadow を使います。間違えても見た目が壊れるだけでエラーにはなりませんが、想定外の表示になるので気をつけましょう。例えば text-shadow をボックス要素に使っても文字にしか影が付かず、要素に影がつくわけではありません。

box-shadowが効かない・表示されない原因と対処

box-shadowを正しく書いたつもりなのに影が見えない、あるいは一部しか見えないというトラブルは頻繁に起こります。原因は大きく5つに絞られるので、順番に確認することで必ず解決できます。まずブラウザの開発者ツールでその要素の computed スタイルを確認し、box-shadow の値が正しく適用されているかを確かめましょう。値が正しく入っているにもかかわらず見えない場合は、以下の原因を順番に潰していきます。

原因1: 親要素にoverflow:hiddenが設定されている

最も多いケースです。box-shadowは要素のボックス外側に描画されるため、親要素に overflow: hidden が設定されていると、はみ出した影がクリッピングされて見えなくなります。特に border-radius を角丸で使っているときに overflow: hidden を一緒に指定しているケースが多く、この組み合わせが落とし穴になります。

/* NG: 親のoverflowが影を消している */
.parent {
  overflow: hidden; /* これが影を切る */
  border-radius: 12px;
}
.child {
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.2); /* 見えない */
}

/* OK: overflow: hiddenを外す */
.parent-fix1 {
  overflow: visible; /* または削除 */
  border-radius: 12px;
}

/* OK: 影を親要素自体に付ける */
.parent-fix2 {
  overflow: hidden;
  border-radius: 12px;
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.2); /* 親に付ける */
}

原因2: z-indexとstacking contextの問題

影が別の要素の下に隠れている場合は、z-indexの重なり順が原因です。box-shadow は要素と同じ重なり階層に描画されるため、上に別の要素が乗っていると隠れます。また、z-index を指定するには position が static 以外である必要があります(relative / absolute / fixed / sticky のいずれか)。position を指定していないと z-index が効かないという点も確認してください。

/* 影が見えない場合はz-indexとpositionを確認 */
.card-with-shadow {
  position: relative; /* position指定がないとz-indexが効かない */
  z-index: 1;
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.2);
}

/* 上に乗っている要素のz-indexを下げる */
.overlay-element {
  position: relative;
  z-index: 0; /* card-with-shadowより低い値にする */
}

原因3: 背景色と影の色が同じ・透明度が高すぎる

影の色に rgba(0,0,0,0.02) のような非常に低い透明度を使っていると、目視では見えません。また、要素と背景の色が同じか非常に近い場合も影は見えにくくなります。透明度を 0.15〜0.25 程度に上げて試してみましょう。逆に、影が「なんか見えてはいるけど弱い」と感じるときも、透明度を上げるか blur を下げるか spread を上げることで解決できます。

/* NG: 透明度が低すぎて見えない */
.invisible-shadow {
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.02);
}

/* OK: 透明度を上げる */
.visible-shadow {
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.18);
}

/* 白背景に白背景の要素では影が目立ちにくい → 要素の背景色を変えるか影の色を変える */
.on-white-bg {
  background: #fff;
  /* 黒ではなくグレーで影をつけると視認しやすい */
  box-shadow: 0px 4px 16px rgba(100, 100, 100, 0.25);
}

原因4: clip-pathを使っている

clip-path を要素に適用すると、overflow: hidden と同様に要素の外にある影がクリッピングされます。clip-path と box-shadow を同時に使うことはできません。代わりに filter: drop-shadow() フィルターを使いましょう。drop-shadow() は clip-path の形状に合わせた影を描画するため、この問題を回避できます。ただし drop-shadow() は inset やカンマによる複数指定ができないため、機能面での制約があります。

/* NG: clip-pathがあるとbox-shadowは消える */
.clipped {
  clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.2); /* 効かない */
}

/* OK: drop-shadow()フィルターで代替する */
.clipped-with-shadow {
  clip-path: polygon(0 0, 100% 0, 100% 80%, 0 100%);
  filter: drop-shadow(0px 8px 12px rgba(0, 0, 0, 0.25));
}

/* 三角形の要素にも影が付く例 */
.triangle {
  width: 0;
  height: 0;
  border-left: 40px solid transparent;
  border-right: 40px solid transparent;
  border-bottom: 70px solid #d16176;
  filter: drop-shadow(0px 4px 8px rgba(0, 0, 0, 0.3));
}

原因5: will-changeやtransformが影響している

will-change: transform や transform: translateZ(0) を指定すると、新しい stacking context が生成され、影の見え方が変わることがあります。GPU合成レイヤーに影が乗る形になるため、親要素との重なりで影が見えなくなるケースがあります。この問題はアニメーション最適化のために will-change を使っているときに起きやすいです。この場合は will-change を外すか、影を付けたい要素と will-change を付ける要素を分離する(wrapper で包む)構造に変えて対処します。

/* NG: will-changeが影響して影が見えなくなる場合 */
.animated-problem {
  will-change: transform;
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.2); /* 場合によって消える */
}

/* OK: wrapperに影を付け、中の要素でアニメーション */
.shadow-wrapper {
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.2);
}
.inner-animated {
  will-change: transform;
  transition: transform 0.3s ease;
}

よくある質問(FAQ)

Q1. box-shadowとfilter: drop-shadow()の違いは何ですか?

box-shadow は要素のボックス(矩形の境界)に対して影を描画します。一方、filter: drop-shadow() はピクセルの形に合わせた影を描画するため、clip-path で切り取った形や PNG画像の透過部分にも対応できます。例えば、不規則な形に clip-path した要素や、背景透過のアイコン画像には drop-shadow() を使います。ただし、drop-shadow() は inset の指定ができず、カンマによる複数の影の重ねがけも利用できません。また、filter はGPUで処理されるためパフォーマンス面で優れる一方、stacking context が変わることで意図しない重なり問題が起きることもあります。通常のUIコンポーネント(カード・ボタン)には box-shadow を、形状の変わった要素や SVG・PNG アイコンには drop-shadow() を使うのが基本の使い分けです。

/* box-shadowはボックス形状に影が付く */
.box {
  box-shadow: 4px 4px 12px rgba(0, 0, 0, 0.2);
}

/* drop-shadowはピクセル輪郭に沿って影が付く(PNG画像などに有効) */
.icon-png {
  filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.3));
}

/* SVGにも有効 */
.icon-svg {
  filter: drop-shadow(2px 4px 6px rgba(209, 97, 118, 0.5));
}

Q2. border-radiusとbox-shadowを同時に使うと角が合わない場合はどうすればいいですか?

box-shadow は border-radius の角の形状を自動的に追従します。同じ要素に両方を指定すれば角丸の影になります。影が角と合っていないように見える場合は、親要素の overflow: hidden が影をクリップしている可能性が高いです。また、spread-radius を大きくしすぎると、角丸の曲率と影の形状がずれて見えることがあります。その場合は spread-radius を 0 か小さい値に戻すと自然になります。border-radius に対して spread-radius を同じ値以上にすると角丸の影が四角くなる場合があるので、両方の値のバランスを取りながら調整しましょう。

/* 正しく設定すれば角丸に合った影になる */
.rounded-card {
  border-radius: 16px;
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.15);
  /* spread-radiusを大きくしすぎない */
}

/* spread-radiusが大きすぎると角丸がズレて見える */
.rounded-card-bad {
  border-radius: 16px;
  box-shadow: 0px 0px 0px 20px rgba(0, 0, 0, 0.1); /* 角丸とズレる */
}

Q3. Safariでbox-shadowが正しく表示されないことがありますか?

主要なモダンブラウザ(Chrome・Firefox・Safari・Edge)はすべて box-shadow をサポートしているため、ベンダープレフィックス(-webkit-box-shadow など)は不要です。ただし、iOS Safariでは overflow: hidden とbox-shadowの組み合わせで表示崩れが起きる場合があります。また、-webkit-overflow-scrolling: touch が設定されたスクロール要素の子要素では影が消えることがあります。その場合は影を親要素に移すか、スクロールコンテナとコンテンツ要素の構造を見直して対処します。iOS 15以降のSafariでは多くの不具合が改善されていますが、古いiOSを対象にする場合は実機テストが必須です。

Q4. box-shadowのアニメーションでパフォーマンスが悪くなった場合の対処法は?

box-shadow のアニメーションはブラウザの再描画(repaint)を引き起こすため、transform や opacity と比べると GPU合成されず、パフォーマンスへの負荷が高くなります。60fps を維持したい場合は、::after 疑似要素で影を作り、その opacity だけをアニメーションする方法が有効です。opacity の変化はコンポジットレイヤーだけで処理されるため、repaint が発生しません。ただし、スマートフォン向けのシンプルなホバーエフェクトであれば、box-shadow の transition でも実用上は問題ないケースがほとんどです。パフォーマンス問題が実際に発生したときに最適化を検討するのが賢明です。

/* パフォーマンス最適化: ::afterで影を作りopacityをアニメーション */
.card-perf {
  position: relative;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.08);
}
.card-perf::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 12px;
  box-shadow: 0px 12px 32px rgba(0, 0, 0, 0.16);
  opacity: 0;
  /* opacityのアニメーションはGPUコンポジット層で処理される */
  transition: opacity 0.3s ease;
}
.card-perf:hover::after {
  opacity: 1;
}

Q5. CSSのbox-shadowでグラデーション影を作ることはできますか?

CSSのbox-shadowは単色しか指定できないため、グラデーションの影を直接作ることはできません。複数の影をカンマで重ねることで近似的なグラデーション影に見せることは可能ですが、厳密にはそれぞれが単色の影の集合です。完全なグラデーション影が必要な場合は、::after 疑似要素に background: linear-gradient() を使い、filter: blur() でぼかして影のように見せる手法が現実的な選択肢です。z-index で本体要素の下に配置するのがポイントです。

/* ::afterを使ったグラデーション影の実装例 */
.card-grad-shadow {
  position: relative;
  border-radius: 12px;
  background: #fff;
  padding: 24px;
}
.card-grad-shadow::after {
  content: "";
  position: absolute;
  bottom: -16px;
  left: 10%;
  width: 80%;
  height: 24px;
  background: linear-gradient(
    to right,
    rgba(209, 97, 118, 0.3),
    rgba(239, 189, 183, 0.6),
    rgba(209, 97, 118, 0.3)
  );
  filter: blur(10px);
  border-radius: 50%;
  z-index: -1;
}

/* 複数シャドウで近似的なグラデーション影 */
.pseudo-grad-shadow {
  box-shadow:
    -8px 8px 16px rgba(209, 97, 118, 0.15),
    0px 8px 24px rgba(0, 0, 0, 0.1),
    8px 8px 16px rgba(239, 189, 183, 0.2);
}

関連記事

CSS・Webデザイン実装の総まとめ

CSSの実装テクニックを「レイアウト・装飾・アニメーション・基礎・トラブル解決」の目的別に探せる総まとめページを用意しています。実装で迷ったときの索引としてどうぞ。

WithCodeを体験できる初級コース公開中!

WithCodeを体験できる初級コース公開中!

初級コース(¥49,800)が完全無料に!

  • 期間:1週間
  • 学習内容:
    ロードマップ/基礎知識/環境構築/HTML/CSS/LP・ポートフォリオ作成
    正しい学習方法で「確かな成長」を実感できるカリキュラム。

副業・フリーランスが主流になっている今こそ、自らのスキルで稼げる人材を目指してみませんか?

未経験でも心配することはありません。初級コースを受講される方の大多数はプログラミング未経験です。まずは無料カウンセリングで、悩みや不安をお聞かせください!

この記事を書いた人

WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。

– service –WithGroupの運営サービス

  • WithCode
    - ウィズコード -

    スクール

    「未経験」から
    現場で通用する
    スキルを身に付けよう!

    詳細はこちら
  • WithFree
    - ウィズフリ -

    実案件サポート

    制作会社のサポート下で
    実務経験を積んでいこう!

    詳細はこちら

公式サイト より
今すぐ
無料カウンセリング
予約!

目次