目次
はじめに
何も言わずにエフェクトを見てください
プロパティをよく読んでください
属性の構文の概要
アウターボックスシャドウとインナーボックスシャドウをプレイするにはどうすればよいですか?
ぼかし半径による境界線のぼかし
缩放阴影尺寸 by spread distance
弄清各图层的z-index
阴影的position
圆角or直角box-shadow傻傻分不清楚?
被割裂的box-shadow
兼容性
感谢
著者がより良い記事を書くことをサポートするためのヒント、ありがとう!
著者について: ^-^Fat John
ホームページ ウェブフロントエンド htmlチュートリアル CSS Magic Hall: Box-Shadow はそれほど単純ではありません:)_html/css_WEB-ITnose

CSS Magic Hall: Box-Shadow はそれほど単純ではありません:)_html/css_WEB-ITnose

Jun 21, 2016 am 08:48 AM

はじめに

ボックスシャドウについて話すとき、最初に考えられるのは、もちろん、それを使用してシャドウを実現することです。実際、この記事は、他の興味深い効果を実現するためにも使用できます。ボックスシャドウのことについて話します。

何も言わずにエフェクトを見てください

3D ボール

<style type="text/css">.ball{  background: rgba(100,100,100,0.2);  width: 100px;  height: 100px;  padding: 10px;  border-radius: 50%;  box-shadow: -14px 8px 100px #333 inset,               0 0 2px #888,          3px -1px 4px #444;}</style><div class="ball"></div>
ログイン後にコピー

紙の影 (@张鑫兴师より)

<style type="text/css">.curved_box {    display: inline-block;    *display: inline;    width: 200px;    height: 248px;    margin: 20px;    background-color: #fff;    border: 1px solid #eee;    -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 60px rgba(0, 0, 0, 0.06) inset;    -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.06) inset;     box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.06) inset;    position: relative;    *zoom: 1;}.curved_box:before {    -webkit-transform: skew(-15deg) rotate(-6deg);    -moz-transform: skew(-15deg) rotate(-6deg);    transform: skew(-15deg) rotate(-6deg);    left: 15px;}.curved_box:after {    -webkit-transform: skew(15deg) rotate(6deg);    -moz-transform: skew(15deg) rotate(6deg);    transform: skew(15deg) rotate(6deg);    right: 15px;}.curved_box:before, .curved_box:after {    width: 70%;    height: 55%;    content: ' ';        -webkit-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);    -moz-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);     box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3);        position: absolute;    bottom: 10px;    z-index: -1;    }</style><div class="curved_box"></div>
ログイン後にコピー

プロパティをよく読んでください

上記のような素晴らしいエフェクトを見て、ボックス シャドウを理解したいと思いませんか?一歩ずつ解読していきましょう!

属性の構文の概要

box-shadow: none | [,]*デフォルト値は none:inset? ,4} && ?シャドウ パターン、デフォルトはアウトセット、つまりアウター ボックス シャドウが使用されます。 inset に設定すると、内側のボックスシャドウが使用されます。 水平オフセット、元の位置からの影の水平方向の変位。正の数値は右への移動を意味し、負の数値は左への移動を意味します。 垂直オフセット、元の位置からの影の垂直方向の変位は、正の数値は下方向に移動することを意味し、負の数値は上方向に移動することを意味します。 ぼかし半径、デフォルト値は 0、シャドウのぼかし半径です。 拡散距離、デフォルト値は 0 で、影の領域を拡大または縮小します。 、影の色、デフォルトは color 属性と一致します。

注: 複数の影を同時に設定でき、影の Z インデックス値は左から右に減少します。

アウターボックスシャドウとインナーボックスシャドウをプレイするにはどうすればよいですか?

デフォルトでは、外側の box-shadow が使用されます。 inset キーワードが box-shadow に追加されると、内側の box-shadow が使用されます。しかし、この 2 つの効果は何でしょうか。

<style type="text/css">.box{  float: left;  background: #888;  width: 100px;  height: 100px;  margin-right: 20px;}.outer-box-shadow{  box-shadow: 10px 10px #F00;}.inner-box-shadow{  box-shadow: 10px 10px #F00 inset;}</style><div class="box outer-box-shadow"></div><div class="box inner-box-shadow"></div></div>
ログイン後にコピー

outer-box-shadow 特徴: 影は要素の境界ボックスの外側に表示されます。実装原理:

  1. 要素の境界ボックスと同じサイズのシャドウ ボックスを作成します。
  2. 要素の境界ボックスと一致するようにシャドウ ボックスを要素の下に配置します。
  3. 水平オフセットと垂直オフセットに基づいて元の位置を基準に移動します。
  4. 拡散距離に基づいてシャドウ ボックスのサイズを調整します (ボックスの変位に影響します)。
  5. ぼかし半径に基づいてシャドウボックスを移動
  6. 最後に、シャドウボックスと要素境界ボックスの重なっている部分を切り出します。

    <style type="text/css">.box{  background: #888;  width: 100px;  height: 100px;}.outer-box-shadow{  box-shadow: 90px 10px #F00;}</style><div class="box outer-box-shadow"></div></div>
    ログイン後にコピー

    シミュレート:

    <style type="text/css">.box{  position: relative;}.box-shadow{  position: absolute;  z-index: -1;  background: #F00;  width: 100px;  height: 100px;  left: 20px;  top: 20px;}.box-content{  background: #888;  width: 100px;  height: 100px;}</style><div class="box">  <div class="box-shadow"></div>  <div class="box-content"></div></div>
    ログイン後にコピー

inner-box-shadow 機能: シャドウは、内の要素。実装原理 (完全に個人的な理解):

  1. 要素のパディング ボックスと同じサイズのシャドウ ボックスを作成します。
  2. 要素のパディング ボックスと一致するようにシャドウ ボックスを配置します。要素 Top;
  3. 要素のパディングエッジと一致するように、水平方向と垂直方向にそれぞれ 2 本の線を描画します (合計 4 本の線が left/top/right/bottom-guideline として記録されます)
  4. 水平オフセットと垂直オフセットに従って、左/上/右/下のガイドラインを移動します。
  5. 拡散距離に応じて4つのラインを移動します。拡散距離が正の数の場合、左のガイドラインは右に移動し、上のガイドラインは下に移動し、右のガイドラインは左に移動し、下のガイドラインは上に移動します。その逆が真です。
  6. ぼかし半径に従って要素の各パディングエッジとそれに対応するガイドラインの間の領域を処理します。
  7. シャドウ ボックスをクリップします
    1. 重ならない領域を切り取ります要素 Part のパディング ボックスを使用します。
    2. 要素の各パディング エッジとそれに対応するガイドラインの間の領域のみを表示します。

      <style type="text/css">.box{  float: left;  background: #888;  width: 100px;  height: 100px;  margin-right: 10px;}.box1{  box-shadow: 0 0 0 20px red inset;}.box2{  box-shadow: 10px 0 0 20px red inset;}.box3{  box-shadow: 10px 0 10px 20px red inset;}.box4{  box-shadow: 0 0 10px 50px red inset;}</style><div class="box box1"></div><div class="box box2"></div><div class="box box3"></div><div class="box box4"></div>
      ログイン後にコピー

      シミュレート:

      <style type="text/css">.box-shadow{  position: relative;  display: inline-block;  background: red;  overflow: hidden;}.bg{  position: absolute;  background: #888;  left: 30px;  right: 10px;  top: 20px;  bottom: 20px;}.content{  position: relative;  z-index: 1;  width: 80px;  height: 80px;  padding: 20px;}</style><div class="box-shadow">  <div class="bg"></div>  <div class="content"></div></div>
      ログイン後にコピー

ぼかし半径による境界線のぼかし

W3C 仕様ではブラウザメーカーがぼかし効果を実現するためにどの方法を使用するかについては規定されていません。とにかく、その効果はガウスぼかし効果とほぼ同じです。ただし、注意する必要があるのは、ぼかし効果により影の範囲が拡大されることです

<style type="text/css">.outline{  border: 1px solid red;  margin: 40px 0;}.s{  background: rgba(255, 100, 100, 0.1);  width: 100px;  height: 100px;}.s1{  box-shadow: 110px 0 0 #333;}.s2{  box-shadow: 110px 0 20px #333;}.s3{  box-shadow: 110px 0 40px #333;}</style><div class="outline">  <div class="s s1">sample1</div></div><div class="outline">  <div class="s s2">sample2</div></div><div class="outline">  <div class="s s3">sample3</div></div>
ログイン後にコピー

sample1 はぼかし半径が 0 の場合の効果です。影のサイズが要素のサイズとまったく同じであることがわかります。そして、sample2はぼかし半径20pxの効果ですが、sample3ではさらに影のサイズが拡大しているのがわかります。ぼかし半径の値が 0 より大きい場合、影のサイズが拡大されることが感覚的に理解できましたが、どの程度拡大されるのでしょうか?次に、まずブレが発生する開始位置を明確にする必要があります。

  1. 对于outer-shadow-box而言,模糊发生的起始位置就是阴影盒子的各边;
  2. 对于inner-shadow-box而言,模糊发生的起始位置就是各guideline。然后模糊效果是从发生的位置,对于水平方向的边或guideline则向垂直方向发散,对于垂直方向的边或guideline则向水平方向发散,且发散的距离相同。发散的距离相同,因此每个方向各发散为blur radius/2的距离。看sample3中阴影尺寸已经与元素盒子重叠了,因为阴影盒子左边框向左发散了20px了,超过它俩之间10px的水平距离了,而sample2则恰恰邻近而已。

缩放阴影尺寸 by spread distance

如果说blur radius是暗地里扩大阴影的尺寸,那么spread distance则是明目张胆地缩放阴影的尺寸了。

<style type="text/css">.outline{  border: 1px solid red;  margin: 40px 0;}.s{  background: rgba(255, 100, 100, 0.1);  width: 100px;  height: 100px;}.s1{  box-shadow: 110px 0 0 #333;}.s2{  box-shadow: 110px 0 0 10px #333;}.s3{  box-shadow: 110px 0 0 -10px #333;}</style><div class="outline">  <div class="s s1">sample1</div></div><div class="outline">  <div class="s s2">sample2</div></div><div class="outline">  <div class="s s3">sample3</div></div>
ログイン後にコピー

还记得《CSS魔法堂:重拾Border之——解构Border》中提及通过border-top/right/bottom/left-colors实现彩虹边框吗?由于兼容性问题和1px对应一种color的缘故,实际应用得很少,但通过outer-box-shadow和spread distance我们就可以得到效果更好,兼容性很高的实现方案了。

<style type="text/css">.rainbow{  margin: 50px;  width: 100px;  height: 100px;  box-shadow: 0 0 0 2px rgb(255,0,0),              0 0 0 5px rgb(255,165,0),              0 0 0 8px rgb(255,255,0),              0 0 0 10px rgb(0,255,0),              0 0 0 12px rgb(0,127,255),              0 0 0 15px rgb(0,0,255),              0 0 0 20px rgb(139,0,255);}</style><div class="rainbow"></div>
ログイン後にコピー

弄清各图层的z-index

上图可以看到没有阴影时,各图层的z-index顺序。那么阴影呢?

  1. 对于outer-box-shadow,则其z-index高于margin图层,低于background-color图层;
  2. 对于inner-box-shadow,则其z-index高于padding图层,低于content图层。

阴影的position

通过horizontal/vertical offset重定位阴影盒子,通过blur radius或spread distance缩放阴影盒子的尺寸,但请注意的是阴影盒子不影响其他盒子的布局,其实阴影盒子就相当于采用absolute定位一样,不会占据Normal flow的空间,也不会影响其他元素的布局,因此仅修改阴影位置或尺寸时,只会触发repaint,而不会触发reflow。

圆角or直角box-shadow傻傻分不清楚?

阴影不仅默认尺寸与元素盒子一致,默认形状也一致。也就是元素盒子采用圆角时,阴影的默认形状也是圆角的。既然说是默认形状一致,就是说可以不一致咯!那到底如何不一致呢,下面我们一起来看个究竟吧!

<style type="text/css">.s1{  background: #0EF;  width: 100px;  height: 100px;  border-radius: 10px;  box-shadow: 110px 0 0 -10px #333,        220px 0 0 0 #666,        360px 0 0 20px #888;}</style><div class="s1">sample1</div>
ログイン後にコピー

当设置spread distance后,border-radius的值也将随之变化,具体公式为border-radius + spread-distance * (1 + (border-radius / spread-distance - 1)^3)。因此spread distance为正数时,border-radius会变大; 而spread distance为负数时,border-radius会减小,直至为0px为止。

被割裂的box-shadow

当设置box-shadow的盒子被拆分为多个盒子时,其对应的box-shadow又会如何呢?其实这不仅仅是box-shadow的问题,如border、background-image等均会遇到同样的问题。CSS3中引入一个新特性box-decoration-break来设置上述情况时的渲染效果。box-decoration-break: slice | cloneslice是默认值,表示首先按未拆分时的状态渲染border、background-image等样式,然后再将其直接拆分为多个盒子;clone表示首先将其直接拆分为多个盒子,然后再逐个盒子渲染border、background-image等样式。

<style type="text/css">.intro{  font-size: 14px;  line-height: 1.5;  text-indent: 1em;  width: 300px;}.intro span{  border: 1px solid #666;  border-radius: 5px;  box-shadow: 5px 3px 3px #AAA;}.slice{  -webkit-box-decoration-break: slice;}.clone{  -webkit-box-decoration-break: clone;}</style><p class="intro"><span class="slice">Hey there, welcome to be here to share something aboute CSS together:) My name is fsjohnhuang, a FE from Midea. Enjoy the evolution of FE, and feel excited in the work I'm doing now.</span></p><p class="intro"><span class="clone">Hey there, welcome to be here to share something aboute CSS together:) My name is fsjohnhuang, a FE from Midea. Enjoy the evolution of FE, and feel excited in the work I'm doing now.</span></p>
ログイン後にコピー

从上面可以看到,与其说box-decoration-break的属性值影响box-shadow的效果,还不如说是box-decoration-break的属性值影响border-radius和border作用到元素盒子的效果,然后由盒子的效果再间接影响box-shadow的效果。

兼容性IE和Edge均不支持,FF支持得最好,而Webkit内核的则要加-webkit-前缀。对于不支持的浏览器,其效果如同box-decoration-break:slice

兼容性

IE9都支持box-shadow多让人可喜可贺的消息啊(因为我工作中只需兼容IE9+就Ok了:))。但IE6~8呢?方案很多啦,上面也有简单的介绍到。@张鑫旭老师提到在模拟blur radius效果时,采用以下方案

.ieBlock{    height:100px;    width:100px;    background:#000;    filter:progid:DXImageTransform.Microsoft.Blur(pixelradius=10);    -ms-filter:"progid:DXImageTransform.Microsoft.Blur(pixelradius=10)"; }
ログイン後にコピー

要比采用以下方案要好!

.shadow {    -moz-box-shadow: 3px 3px 4px #000;    -webkit-box-shadow: 3px 3px 4px #000;    box-shadow: 3px 3px 4px #000;    /* For IE 8 */    -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000')";    /* For IE 5.5 - 7 */    filter: progid:DXImageTransform.Microsoft.Shadow(Strength=4, Direction=135, Color='#000000');}
ログイン後にコピー

另外若想不假思索地用到生产环境中,还是用成熟的CSS库较好。具体请参考PIE使IE支持CSS3圆角盒阴影与渐变渲染

感谢

the-box-shadowbreak-decorationCSS3 box-shadow实现纸张的曲线投影效果CSS实现跨浏览器兼容性的盒阴影效果CSS实现跨浏览器的box-shadow盒阴影效果(2)PIE使IE支持CSS3圆角盒阴影与渐变渲染《图解CSS3核心技术与案例实战》 —— 3.5 CSS3盒子阴影属性

打赏支持作者写出更多好文章,谢谢!

著者に報酬を与えます

著者がより良い記事を書くことをサポートするためのヒント、ありがとう!

支払い方法を選択してください

著者について: ^-^Fat John

個人フロントエンドスタックエンジニアのホームページ · 私の記事 · 1 ·

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? 公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? Mar 04, 2025 pm 12:32 PM

公式アカウントのWebページはキャッシュを更新します。これはシンプルでシンプルで、ポットを飲むのに十分な複雑です。あなたは公式のアカウントの記事を更新するために一生懸命働きましたが、ユーザーはまだ古いバージョンを開くことができますか?この記事では、この背後にあるtwist余曲折と、この問題を優雅に解決する方法を見てみましょう。それを読んだ後、さまざまなキャッシュの問題に簡単に対処でき、ユーザーが常に新鮮なコンテンツを体験できるようになります。最初に基本について話しましょう。それを率直に言うと、アクセス速度を向上させるために、ブラウザまたはサーバーはいくつかの静的リソース(写真、CSS、JSなど)やページコンテンツを保存します。次回アクセスするときは、もう一度ダウンロードすることなく、キャッシュから直接検索できます。自然に高速です。しかし、このことは両刃の剣でもあります。新しいバージョンはオンラインです、

HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? Mar 17, 2025 pm 12:27 PM

この記事では、ブラウザのユーザー入力を直接検証するために、必要、パターン、MIN、MAX、および長さの制限などのHTML5フォーム検証属性を使用して説明します。

WebページのPNG画像にストローク効果を効率的に追加する方法は? WebページのPNG画像にストローク効果を効率的に追加する方法は? Mar 04, 2025 pm 02:39 PM

この記事では、CSSを使用したWebページへの効率的なPNG境界追加を示しています。 CSSはJavaScriptやライブラリと比較して優れたパフォーマンスを提供し、微妙または顕著な効果のために境界幅、スタイル、色を調整する方法を詳述していると主張しています

HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? Mar 17, 2025 pm 12:20 PM

記事では、HTML5クロスブラウザーの互換性を確保するためのベストプラクティスについて説明し、機能検出、プログレッシブエンハンスメント、およびテスト方法に焦点を当てています。

&lt; datalist&gt;の目的は何ですか 要素? &lt; datalist&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:33 PM

この記事では、HTML&lt; Datalist&GT;について説明します。オートコンプリートの提案を提供し、ユーザーエクスペリエンスの改善、エラーの削減によりフォームを強化する要素。

&lt; meter&gt;の目的は何ですか 要素? &lt; meter&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:35 PM

この記事では、html&lt; meter&gt;について説明します。要素は、範囲内でスカラーまたは分数値を表示するために使用され、Web開発におけるその一般的なアプリケーション。それは差別化&lt; Meter&gt; &lt; Progress&gt;およびex

&lt; Progress&gt;の目的は何ですか 要素? &lt; Progress&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:34 PM

この記事では、HTML&lt; Progress&gt;について説明します。要素、その目的、スタイリング、および&lt; meter&gt;との違い要素。主な焦点は、&lt; Progress&gt;を使用することです。タスクの完了と&lt; Meter&gt; statiの場合

HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? Mar 12, 2025 pm 04:05 PM

この記事では、html5&lt; time&gt;について説明します。セマンティックデート/時刻表現の要素。 人間の読み取り可能なテキストとともに、マシンの読みやすさ(ISO 8601形式)のDateTime属性の重要性を強調し、Accessibilitを増やします

See all articles