box-shadow を作る
box-shadow: 横のずれ 縦のずれ ぼかし 広がり 色;
いま 0px 4px 12px 0px rgba(26, 26, 26, 0.25) で描いています。この文字と、下に出るコードは同じものです。
1枚目/外側/横のずれ 0px/縦のずれ 4px/ぼかし 12px/広がり 0px/色 #1a1a1a/こさ 25%
いまの色は rgba(26, 26, 26, 0.25)。8桁の16進で書けば #1a1a1a40 です(下2桁が こさ。0〜255の256段階なので、rgba の数とわずかにずれます)。
box-shadow: 0px 4px 12px 0px rgba(26, 26, 26, 0.25);
影を1枚重ねています。カンマで区切れば何枚でも重なります。どれだけ重ねても、箱の大きさは1pxも変わりません。
よくある質問
「ぼかし」と「広がり」は何が違うのですか?
ぼかしは縁のにじみ方、広がりは影そのものの大きさです。ぼかしを大きくしても影の届く範囲は広がりますが、それは縁がぼやけて薄く伸びているだけで、影の形は元の箱と同じ大きさのままです。広がりは形そのものを四方に大きくします。だから、ぼかし0のまま広がりだけを大きくすると、輪郭のはっきりした一回り大きい影になります。広がりはマイナスにもできて、そのときは影が小さくなります。
広がりにマイナスを入れられますか? ぼかしはどうですか?
広がりはマイナスにできます。CSSの仕様が「正の値は四方に広げ、負の値は縮める」と定めています。一方、ぼかしにマイナスは書けません。仕様が「負の値は無効」と明記していて、無効な値を書くとその影の指定そのものが読み飛ばされます。影を小さくしたいときは、ぼかしではなく広がりをマイナスにします。
影をつけると、まわりのものがずれませんか?
ずれません。CSSの仕様が「影はレイアウトに影響しない」と定めていて、スクロールできる範囲も広げないと書かれています。同じ太さのborderをつけると要素が大きくなってまわりを押しのけますが、box-shadowはいくら大きくしても、いくつ重ねても、要素の大きさは1pxも変わりません。
inset を付けると何が変わりますか?
影が内側に落ちて、へこんで見えます。仕様の言い方では、外側の影が「箱が地面から持ち上がって、地面に影を落とす」形なのに対し、insetは「箱の形に地面が切り抜かれて、そこへずれ込んだ」形です。だから外側の影とinsetの影は上下が逆に見えます。同じ要素に外側とinsetの両方を書くこともできます。
影は何枚まで重ねられますか?
カンマで区切れば何枚でも書けます。仕様の書き方では「カンマで区切った影の並び」で、先に書いたものが手前、あとに書いたものが奥に描かれます。立体感は1枚では出にくく、近い影・中くらいの影・遠い影を重ねると自然に見えます。重ねても要素の大きさは変わりません。
影の色を薄くするには opacity を使うのですか?
使いません。opacityは要素そのものを薄くしてしまうので、中の文字まで薄くなります。影だけを薄くしたいときは、色の側で薄さを指定します。rgba(0, 0, 0, 0.25) の4つ目の数か、8桁の16進 #00000040 の下2桁がそれにあたります。8桁の下2桁は0〜255の256段階なので、rgbaの0.25とはわずかに違う値になります。
色を書かないとどうなりますか?
その要素の文字の色(currentColor)になります。仕様が「色を省いたときの既定はcurrentColor」と定めているためです。長さも同じで、省いたぶんは0として扱われます。box-shadow: 4px 4px; と書くと、ぼかし0・広がり0・文字と同じ色の影が右下に出ます。
文字に影をつけるときも同じですか?
似ていますが、使える数が違います。文字の影は text-shadow で、こちらには広がりもinsetもありません。仕様に「広がりの値とinsetキーワードは使えない」と明記されています。つまり文字の影で書けるのは、横のずれ・縦のずれ・ぼかしの3つと色だけです。
つまみを動かすと影ができて、そのまま貼れる CSS が出ます。ぼかしは縁のにじみ、広がりは影そのものの大きさです。
4つの数は、左から順に「横・縦・ぼかし・広がり」です
box-shadow のうしろに並ぶ数は、いつもこの順です。 名前を覚えるより、1つ目と2つ目が「どこへ」、3つ目と4つ目が「どんな形か」と分けて見るほうが早く読めます。
- 1つ目 ── 横のずれ。正の数で右へ、負の数で左へずれます
- 2つ目 ── 縦のずれ。正の数で下へ、負の数で上へずれます
- 3つ目 ── ぼかし。0 なら縁がはっきりします。マイナスは書けません
- 4つ目 ── 広がり。影そのものの大きさ。マイナスも書けます
数を省くと、そこは 0 として扱われます。色を省くと文字と同じ色(currentColor)になります。だからbox-shadow: 4px 4px; だけでも、右下にくっきりした影が出ます。
⭐ 「ぼかし」と「広がり」は、まったく別のものです
ここがいちばん取り違えるところです。下の4つは、どれも「下に16pxずらした影」で、変えた数は1つだけです。 並べて見ると、2つが別のことをしているのが分かります。
0px 16px 0px 0px #0017c1下に16pxずらしただけ。縁がはっきりしていて、箱と同じ大きさです。0px 16px 16px 0px #0017c1縁がにじみました。大きさはそのままです。0px 16px 0px 16px #0017c1影そのものが四方に16px大きくなりました。縁ははっきりしたままです。0px 16px 0px -8px #0017c1影が四方に8px小さくなりました。広がりだけがマイナスにできます。ぼかしを大きくしても、影の形は箱と同じ大きさのままです。 縁がにじんで外へ薄く伸びるので大きくなったように見えますが、濃いところは1mmも広がっていません。 いっぽう広がりは、形そのものを四方に大きくします。 だから広がりだけを動かすと、輪郭がはっきりしたまま一回り大きい影になります。
広がりはマイナスにできます。マイナスにすると影が小さくなるので、 「下にちょっとだけ影を見せる」ような作り方ができます。 これに対してぼかしにマイナスは書けません。 CSS の仕様がそこだけ「負の値は無効」と決めていて、 無効な値を書くと、その影の指定そのものが読み飛ばされます。
にじみの幅は、ぼかしの数のおよそ2倍です
仕様は、ぼかしを「ぼかしの数の半分を標準偏差にしたガウスぼかし(新しいタブで開きます)に近づけること」と定めています。 その結果、色が変わっていく帯の幅はぼかしの数の約2倍になり、しかも影の縁をまたいで内側と外側に半分ずつ広がります。 ぼかし16pxなら、およそ32pxかけて色が薄れていく、ということです。
影は場所を取りません。border との決定的な違いです
box-shadow で ずれ0・ぼかし0・広がりだけ と書くと、枠線とほとんど同じ見た目になります。 下の2列は、どちらも12px の青い縁を真ん中の箱に足したものです。 上が影、下が border です。
影(0px 0px 0px 12px #0017c1)
border(12px solid #0017c1)
上の列は、両どなりの箱が動いていません。下の列は、真ん中の箱が大きくなったぶん、両どなりが押しのけられています。
CSS の仕様は影について「影はレイアウトに影響しない」「スクロールできる範囲も広げない」と、はっきり書いています。 だから影は何枚重ねても、要素の大きさは変わりません。 押したときだけ枠を出したいような場面で border を足すとまわりがガタッと動いてしまうのは、この違いのためです。
inset にすると、へこんで見えます
inset と書き足すと、影が内側に落ちます。 仕様の説明が分かりやすいので、そのまま書きます。
- 外側の影 ── 箱が地面から持ち上がって、地面に影を落としている形
- 内側の影(inset) ── 箱の形に地面が切り抜かれて、そこへずれ込んだ形
同じ「下へ4px」でも、外側なら影は箱の下に出て、inset なら箱の中の上のふちに出ます。上下が逆に見えるのはこのためです。 へこんだボタンや、押し込まれた入力欄は、たいていこれで作られています。外側と inset は同じ要素に両方書けます。
立体感は1枚では出ません。カンマで区切って重ねます
影はカンマで区切って何枚でも重ねられます。 仕様の書き方では「カンマで区切った影の並び」で、先に書いたものが手前、あとに書いたものが奥に描かれます。
本物の影を思い出すと、物に近いところは濃くて小さく、遠いところは薄くて大きいはずです。1枚の影ではこれを同時に表せません。だから近い影・中くらいの影・遠い影の3枚を重ねます。 上の道具の「3枚重ね」と「1枚だけ」を押し比べてみてください。
重ねるときに効くのが広がりのマイナスです。 遠い影ほど広がりを少しマイナスにして小さくしておくと、 下だけに影が残って、横へふくらんだ感じが消えます。
影の薄さは opacity ではなく、色の側で決めます
影を薄くしたいとき、要素そのものを薄くしてはいけません。 それをすると中の文字まで薄くなり、読みにくくなります。 薄くするのは影の色のほうです。書き方は2つあります。
rgba(0, 0, 0, 0.25)── 4つ目の数が濃さ。0 で透明、1 でそのままの色#00000040── 8桁の16進。下2桁が濃さで、00で透明、ffでそのままの色
この2つはぴったり同じ値にはなりません。8桁の下2桁は0〜255の256段階なので、25%にいちばん近い 40(=64)は0.2509…になります。上の道具は両方の書き方を並べて出しているので、 見比べてみてください。
文字の影には、広がりも inset もありません
文字に影をつけるのは text-shadow で、書き方は似ています。 ただし仕様に「広がりの値と inset キーワードは使えない」と明記されていて、 書けるのは横のずれ・縦のずれ・ぼかしの3つと色だけです。
もう1つ違いがあります。外側の box-shadow は、箱の中では切り取られます(箱のうしろに影が残らない)。 いっぽう text-shadow は切り取られないので、 文字の色を半透明にすると文字の下から影が透けて見えます。
このページの文法と決まりは、すべて W3C の仕様そのものから取っています。 影の4つの数・inset・重ね順・「影はレイアウトに影響しない」はCSS Backgrounds and Borders Module Level 3(新しいタブで開きます)、8桁の16進と rgba() はCSS Color Module Level 4(新しいタブで開きます)、text-shadow に広がりと inset が無いことはCSS Text Decoration Module Level 3(新しいタブで開きます)です。 見本の地を白い地と暗い地の2つ用意しているのは、影が「うしろの面が何色か」で見え方の変わるものだからで、 ここだけはサイトの明暗の設定に合わせていません。