提及box-shadow那第一個想法固然就是用來實現陰影,其實它還能用於實現其餘好玩的效果的,本篇就打算說說box-shadow的那些事。css
3D小球
html
<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>
紙張陰影(來自@張鑫旭老師)
css3
<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呢?下面咱們來一步步解密它吧!web
box-shadow: none | <shadow>[,<shadow>]*
默認值爲none
<shadow>
:inset? && <length>{2,4} && <color>?
shadow pattern,默認爲outset,即採用outer box-shadow。經過設置爲inset時,則採用inner box-shadow。
horizontal offset,陰影距離原位置的水平位移,正數表示向右移動,負數表示向左移動。
vertical offset,陰影距離原位置的垂直位移,正數表示向下移動,負數表示向上移動。
blur radius,默認值爲0,陰影模糊度半徑。
spread distance,默認值爲0,擴展或縮小陰影的做用面積。
<color>
,陰影顏色,默認與color
屬性一致。瀏覽器
注意:咱們能夠同時設置多個陰影,而陰影的z-index值從左向右遞減。ide
默認狀況下采用的是outer box-shadow,當在box-shadow
中添加inset關鍵詞後,則採用inner box-shadow了,但到底它倆的效果是如何的呢?
wordpress
<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
特色:陰影落在元素的border box以外。
實現原理:佈局
horizontal offset
和vertical offset
來相對原位置做移動;spread distance
縮放陰影盒子的尺寸(會影響盒子的位移);blur radius
對陰影盒子做加工;<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>
模擬一下:
ui
<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
特色:陰影落在元素的padding box以內。
實現原理(純我的理解):idea
horizontal offset
和vertical offset
移動left/top/right/bottom-guideline。spread distance
移動4條線。spread distance爲正數時,left-guideline向右移動,top-guideline向下移動,right-guideline向左移動和bottom-guidelien向上移動;spread distance爲負數時,則相反。blur radius
加工元素各padding edge至其對應的guideline間的區域.<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>
blur radius
W3C spec中沒有規定瀏覽器廠商使用哪一種方式實現模糊效果,反正效果與高斯模糊效果差很少就是了。但有一點咱們須要注意的,那就是模糊效果會擴大陰影的面積。
<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是blur radius
爲0的效果,能夠看到陰影尺寸與元素尺寸如出一轍。而sample2是blur radius
爲20px的效果,能夠看到陰影尺寸有所擴展了,而sample3則擴展得更多一些。
如今咱們感性上認知到blur radius
值大於0時會擴展陰影尺寸,那麼到底擴展多少呢?那咱們要先明確模糊發生的起始位置了。
blur radius/2
的距離。看sample3中陰影尺寸已經與元素盒子重疊了,由於陰影盒子左邊框向左發散了20px了,超過它倆之間10px的水平距離了,而sample2則偏偏鄰近而已。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順序。那麼陰影呢?
經過horizontal/vertical offset
重定位陰影盒子,經過blur radius
或spread distance
縮放陰影盒子的尺寸,但請注意的是陰影盒子不影響其餘盒子的佈局,其實陰影盒子就至關於採用absolute定位同樣,不會佔據Normal flow的空間,也不會影響其餘元素的佈局,所以僅修改陰影位置或尺寸時,只會觸發repaint,而不會觸發reflow。
陰影不只默認尺寸與元素盒子一致,默認形狀也一致。也就是元素盒子採用圓角時,陰影的默認形狀也是圓角的。既然說是默認形狀一致,就是說能夠不一致咯!那到底如何不一致呢,下面咱們一塊兒來看個究竟吧!
<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的問題,如border、background-image等均會遇到一樣的問題。CSS3中引入一個新特性box-decoration-break
來設置上述狀況時的渲染效果。
box-decoration-break: slice | clone
slice是默認值,表示首先按未拆分時的狀態渲染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圓角盒陰影與漸變渲染
尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/5477194.html^_^肥仔John
the-box-shadow
break-decoration
CSS3 box-shadow實現紙張的曲線投影效果
CSS實現跨瀏覽器兼容性的盒陰影效果
CSS實現跨瀏覽器的box-shadow盒陰影效果(2)
PIE使IE支持CSS3圓角盒陰影與漸變渲染 《圖解CSS3核心技術與案例實戰》 —— 3.5 CSS3盒子陰影屬性