コラム・豆知識
box-shadowプロパティによる奥行き表現の基礎
box-shadowプロパティは、要素に影を追加することで、フラットなデザインに立体感を与えます。構文はbox-shadow: x軸オフセット y軸オフセット ぼかし半径 広がり半径 色の順序で指定します。x軸とy軸のオフセットで影の位置を制御し、正の値で右下、負の値で左上に影が配置されます。
ぼかし半径の値が大きいほど、影の輪郭がソフトになります。box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1)のような微妙な影は、カード型UIに奥行きを与えながらも過度に目立たない、モダンWebデザインの定番です。Material Designのエレベーション(高さ)概念も、この影の濃淡で表現されています。
広がり半径は、影のサイズを拡大または縮小します。正の値で影が要素より大きくなり、負の値で小さくなります。box-shadow: 0 0 0 3px #blueのように、ぼかしをゼロにして広がり半径のみ指定すると、アウトライン効果を実現できます。outlineプロパティと異なり、角丸に追従する特性があります。
複数の影を重ねることで、より複雑な表現が可能です。box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)のようにカンマで区切って指定することで、異なる距離感の影を同時に適用できます。この多層的な影が、よりリアルな浮遊感を生み出します。
inset指定による内側の影と凹凸表現
insetキーワードを追加することで、影が要素の内側に描画されます。box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2)という指定により、要素が凹んでいるような視覚効果を生み出せます。フォーム入力欄に適用すると、物理的な窪みを感じさせる表現になります。
ボタンの押下状態の表現に、inset shadowが効果的です。通常時は外側の影で浮き上がって見せ、:active疑似クラスでinset shadowに切り替えることで、押し込まれたような視覚的フィードバックを提供できます。transitionプロパティと組み合わせることで、滑らかな状態遷移を実現します。
内側と外側の影を同時に適用することも可能です。box-shadow: inset 0 2px 4px rgba(0,0,0,0.1), 0 4px 6px rgba(0,0,0,0.1)のように指定することで、縁が盛り上がったフレームのような立体表現を作れます。スキューモーフィズムデザインでの質感表現に活用されてきた技法です。
グラスモーフィズムとの併用では、inset shadowにより半透明要素の境界を強調できます。backdrop-filterプロパティでぼかした背景に、微妙なinset shadowを加えることで、ガラスの厚みを感じさせる表現が可能です。ただし、過度な影は視認性を損なうため、控えめな適用が推奨されます。
drop-shadowフィルターとbox-shadowの使い分け
filter: drop-shadow()は、要素の形状に沿った影を生成します。box-shadowが矩形の境界ボックスに影を付けるのに対し、drop-shadow()は透明部分を除外して影を描画します。PNG画像やSVG、擬似要素の形状に正確に追従する影を実現できます。
構文はfilter: drop-shadow(x y ぼかし 色)で、広がり半径の指定がない点がbox-shadowとの違いです。img要素にfilter: drop-shadow(4px 4px 8px rgba(0,0,0,0.3))を適用すると、画像の輪郭に沿った自然な影が生成されます。背景が透明なロゴやアイコンでの活用が効果的です。
パフォーマンスの観点では、drop-shadow()はbox-shadowより計算コストが高くなります。特に複雑な形状や、大量の要素に適用する場合、レンダリング性能への影響が顕著です。装飾的な用途に限定し、UI全体への無制限な適用は避けるべきです。
ブラウザサポートは、IE11を除く主要ブラウザで安定しています。ただし、Safari の古いバージョンでは-webkit-filterプレフィックスが必要な場合があります。Autoprefixerによる自動付与が推奨されますが、レガシー環境への対応が不要なプロジェクトでは、標準構文のみで問題ありません。
text-shadowによるテキスト装飾と可読性向上
text-shadowプロパティは、テキストに影を追加します。構文はtext-shadow: x y ぼかし 色で、box-shadowから広がり半径とinset指定を除いた形式です。h1やh2要素の見出しに適用することで、視覚的な強調効果を生み出せます。
背景画像の上に配置したテキストの可読性向上に、text-shadowが有効です。text-shadow: 1px 1px 2px rgba(0,0,0,0.8)のような濃い影を付けることで、複雑な背景に対してもテキストの輪郭が明確になります。ヒーローセクションでの白文字テキストに頻繁に使用される技法です。
発光効果の表現にも活用できます。text-shadow: 0 0 10px #00ff00, 0 0 20px #00ff00のように、オフセットをゼロにして複数の影を重ねることで、ネオンサインのような光の滲みを再現できます。SF映画風やサイバーパンクスタイルのデザインでの演出に効果的です。
アクセシビリティの観点では、過度なtext-shadowが可読性を損なう場合があります。特に小さなフォントサイズでは、影によってテキストが読みづらくなります。WCAG 2.1のガイドラインでは、装飾が情報伝達を妨げないよう求められており、視覚効果と可読性のバランスが重要です。
パフォーマンス最適化とデザインシステムへの統合
複雑な影の計算は、ブラウザのレンダリングエンジンに負荷を与えます。特に:hover疑似クラスでアニメーションさせる場合、影のぼかし半径や色を変化させると、GPU処理が効かずCPU描画となります。transformやopacityのアニメーションと比較して、パフォーマンスが大幅に劣化します。
代替手法として、事前に異なる影を持つクラスを用意し、transition: opacityで切り替える実装が推奨されます。あるいは、擬似要素::beforeや::afterに影を持たせた要素を配置し、opacityのみをアニメーションさせることで、滑らかな視覚変化とパフォーマンスを両立できます。
デザインシステムでは、影のパターンを標準化することが重要です。Material Designの24段階のエレベーションや、TailwindCSSの影クラスを参考に、プロジェクト固有の影パレットを定義します。CSS変数として--shadow-sm、--shadow-md、--shadow-lgのように管理することで、一貫性のある適用が可能です。
印刷時には、影が正しく出力されない、またはインクの無駄遣いになる場合があります。@media printメディアクエリ内でbox-shadow: noneを指定し、影を削除することが一般的です。請求書や契約書といった正式文書では、装飾的な影を排除し、情報の明確な伝達を優先すべきです。この配慮が、印刷コスト削減と環境への配慮にもつながります。