深入理解box-shadow的渲染

box-shadow這個屬性,目的為框盒子添加陰影,使用起來也不是十分復雜。但是最近在開展單位的前端cop項目時,發(fā)現(xiàn)此屬性不簡單,還可以這樣用,而且會發(fā)現(xiàn)一些看似復雜好玩的東西竟然是用box-shadow實現(xiàn)的。
網(wǎng)上介紹這個屬性的大部分文章都是介紹怎么使用,各個屬性值怎么設置會有如何的效果之類的,少有深入探討,感覺讀完之后知其然,卻不知所以然,無法清晰融會。于是下來好好研究了一下,總結(jié)如下。
使用語法:

    box-shadow: x-shadow y-shadow blur-radius spread-radius color type;

各屬性值含義:

  • x-shadow:水平陰影的偏移,當值為正時,陰影往x軸正向偏移,即水平向右;反之,值為負時,陰影往x軸反向偏移,即水平向左
  • y-shadow:垂直陰影的偏移,當值為正時,陰影往y軸正向偏移,即垂直向下;反之,值為負時,陰影往y軸反向偏移,即垂直向上
  • blur-radius:模糊距離,不能為負值;為0表示不模糊,值越大,陰影的邊緣就越大,也就越模糊
  • spread-radius:陰影的尺寸,參數(shù)可選,不設置為0;正值表示陰影擴展,負值表示陰影反向縮小,可抵消偏移和模糊距離的尺寸
  • color:陰影的顏色,參數(shù)可選,不設置便使用瀏覽器的默認色,因為各瀏覽器的默認色不同,推薦還是設置一下
  • type:陰影類型,參數(shù)可選,不設置默認outset(外部陰影), 還有inset(內(nèi)部陰影)

1、外部陰影

當type不設置或設置為outset時,是為外部陰影,例如:

box-shadow: 5px 5px 5px 5px #ccc;
box-shadow: 5px 5px 5px 5px #ccc outset;

外部陰影在瀏覽器渲染時一般是如下幾步實現(xiàn)的,

  1. 根據(jù)color克隆一個和原始元素相同尺寸的元素“覆蓋”其上
  2. 根據(jù)spread-radius向四周增加對應顏色的陰影,類似于“邊框”
  3. 然后根據(jù)指定的x-shadow 和 x-shadow 將克隆出來的元素進行偏移
  4. 根據(jù)指定的blur-radius設置模糊半徑,一般是依據(jù)高斯算法進行模糊處理,本質(zhì)上是在陰影邊緣將陰影色往純透明色之間進行顏色過渡,所以看到是模糊是逐漸變淡的;而且據(jù)了解blur是沿邊緣線兩邊各一半距離,并從里向外擴散
  5. 最后,將克隆元素與原始原屬的交集“剪切”去,剩余部分便是最終陰影效果

各步大概的圖示如下:

box-shadow-outset.png

為了更加方便的觀察這個原理,圖中特意設置了透明度,可進入外部陰影觀察動態(tài)效果
最終的陰影尺寸為:

  • top陰影: spread-radius - y-shadow + blur-radius/2
  • left陰影: spread-radius - x-shadow + blur-radius/2
  • bottom陰影: spread-radius + y-shadow + blur-radius/2
  • right陰影: spread-radius + x-shadow + blur-radius/2

當模糊距離為0,只有spread-radius時,效果相當于border,但這并不是真正的border,盒子模型計算時寬高不會被計算在內(nèi)

2、內(nèi)部陰影

當type設置為inset時,是為內(nèi)部陰影,例如:

box-shadow: 5px 5px 5px 5px #ccc inset;

個人理解,內(nèi)部陰影在瀏覽器渲染時一般是如下幾步實現(xiàn)的,

  1. 根據(jù)color克隆一個比原始元素相同尺寸大的元素“覆蓋”其上
  2. 根據(jù)spread-radius向四周沿著border向內(nèi)切割掉部分克隆的元素,留下對應尺寸的spread
  3. 然后根據(jù)指定的x-shadow 和 x-shadow 將克隆出來的元素進行偏移
  4. 根據(jù)指定的blur-radius設置模糊半徑,一般是依據(jù)高斯算法進行模糊處理,本質(zhì)上是在陰影邊緣將陰影色往純透明色之間進行顏色過渡,所以看到是模糊是逐漸變淡并向外擴散的
  5. 最后,將克隆元素在原始原始邊框外面的部分“剪切”去,剩余部分便是最終陰影效果

各步大概的圖示如下:


box-shadow-inset.png

為了更加方便的觀察這個原理,圖中特意設置了透明度,可進入內(nèi)部陰影觀察動態(tài)效果

最終的陰影尺寸為:

  • top陰影: spread-radius + y-shadow + blur-radius/2
  • left陰影: spread-radius + x-shadow + blur-radius/2
  • bottom陰影: spread-radius - y-shadow + blur-radius/2
  • right陰影: spread-radius - x-shadow + blur-radius/2

3、多個陰影及層級關系

1) 多個陰影
當多個陰影重疊時,聲明在前面會覆蓋后面的,比如:

box-shadow: 0px 0px 5px 10px blue, 0px 0px 5px 20px red;

其中前面的藍色陰影會覆蓋后面的紅色陰影

2) 層級關系
有了框陰影,便有了內(nèi)外陰影,元素邊框,背景和內(nèi)容等的呈現(xiàn)層級關系,一般為如下層級關系:
border > 內(nèi)陰影 > background-image > background-color > 外陰影
可以點擊此處試一試: 內(nèi)部陰影

附:幾個box-shadow的demo

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容