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

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

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)部陰影