box-shadow 在前端的 CSS 編寫工作想必十分常見。但是 box-shadow 除去它的常規用法,其實還存在許多不為人知的奇技淫巧。 喜歡 markdown 版本的可以戳這裡 。 box-shadow 常規用法 說到 box-shadow ,首先想到的必然是它能夠生成陰影,所以稱之為 sh ...
box-shadow 在前端的 CSS 編寫工作想必十分常見。但是 box-shadow 除去它的常規用法,其實還存在許多不為人知的奇技淫巧。
box-shadow 常規用法
說到 box-shadow ,首先想到的必然是它能夠生成陰影,所以稱之為 shaodow ,簡單看看它的語法:
基礎屬性語法
box-shadow
屬性向框添加一個或多個陰影。
box-shadow: h-shadow v-shadow blur spread color inset;
像這樣 box-shadow: 10px 10px 5px #888888;
除此之外,我們要知道,box-shadow 是分外 shadow 和內 shadow 的,內陰影即是在屬性上添加 inset 。
OK,本文已經假設你對 box-shadow 有了一定的瞭解,在此基礎上,我們再看看 box-shadow 有什麼其它妙用。
box-shadow 模擬多邊框
通常而言,我們會給許多元素添加邊框 border
,但是當如果需要多重邊框,這個時候,由於 border
單重的限制,box-shadow 就可以閃亮登場了。我們可以輕鬆的使用外陰影或者內陰影來模擬邊框效果。
可以看到,由內至外,這裡利用 box-shadow ,設置了白色、黑色、灰色三層邊框及最外層帶模糊的陰影。
box-shadow 有一個參數是設置 blur 的,即是模糊的距離,在上面的例子中,即是第二重陰影 0 0 0 10px #333,
中的第三個 0 ,當 blur 的值為 0 ,那麼陰影本身是不會模糊的,那麼就很容易模擬出邊框的效果。
而且,元素可以設置多重陰影,並且它們存在層疊關係,離 box-shadow 最近設置的層疊優先順序最高,依次遞減,這個對照代碼很好理解。
當然,值得註意的是:
-
陰影並不是邊框,它們並不占有實際的空間,也不能歸屬於
box-sizing
的範圍。不過,你可以通過使用內邊距或外邊距(取決於陰影是內部的還是外部的)占據額外的空間來模擬。 -
上述示例模擬的邊框是位於元素外部的。它不能捕獲類似懸停和點擊的滑鼠事件。如果事件很重要,那麼可以通過添加 inset 關鍵字讓陰影出現在元素的內部。註意,你可能需要添加額外的內邊距來擴充空間。
box-shadow 模擬半透明遮罩層
很多時候,我們需要用到類似下圖這樣的遮罩層,通過半透明遮罩層把背景調暗,凸顯某些 UI 組件,提升用戶體驗。
常規的做法通常都會用到一個額外的元素,用作遮罩層,至少也是一個偽元素, before
或者 after
。
不考慮低版本的相容性的話,其實用 box-shadow 也可以模擬遮罩層這種效果。
這裡還有一個例子,hover 時利用配合 scale 放大元素, box-shadow 產生遮罩,聚焦用戶關註視野。
當然,值得註意的是:
-
使用這種方法不可避免的需要考慮相容性,IE9+、Firefox 4、Chrome、Opera 以及 Safari 5.1.1 支持 box-shadow 屬性。
-
由於每個人的瀏覽器視口大小不一致,為了所有情況下 box-shadow 生成的陰影都能覆蓋整個頁面,可能需要將陰影的尺寸
spread
設置的很大。 -
如果你真的想嘗試這個方法,box-shadow 從性能角度而言屬於
耗性能樣式
,不同樣式在消耗性能方面是不同的,box-shadow 從渲染角度來講十分耗性能,原因就是與其他樣式相比,它們的繪製代碼執行時間過長。雖然有 GPU 的 3D 加速,但是具體使用的時候還是值得斟酌考慮。不過你要知道,沒有不變的事情,在今天性能很差的樣式,可能明天就被優化,並且瀏覽器之間也存在差異。
下麵再講講多重 box-shadow 能幹啥:
多重 box-shadow 之簡單圖形
從本質上講,box-shadow 是將自身投影到另一個地方,在很多情況下,我們是可以利用 box-shadow 來複制自身的!
利用這個特性,我們可以用 box-shadow 製作一些簡單的圖形,在我的單標簽圖形 Demo 中,有這樣一個圖形:
其中的雲層,就是利用了 多重box-shaodw
在一個偽元素內生成的。下麵我利用不同的顏色,直觀的表達一下如何利用 box-shadow 繪製這個圖形:
當所有陰影的顏色都是同色的時候,就很自然變成了一朵雲朵:
當然,腦洞夠大的話,更複雜一點的也是可以的,來看看下麵這個圖形,也是由單個標簽完成:
其中比較困難的是其中環繞字母 e 的那個圓以及那個切入的不規則角,看看用陰影怎麼把它做出來,利用了兩重 box-shadow:
嗯,當然,你問我這些圖形有什麼用。我覺得實用性真的不強吧,我個人而言是興趣,從中獲取到了樂趣,同時也學到了很多東西,對屬性本身印象也更加深刻,遇到許多 CSS 方面的問題的時候,思路更加開闊。
更多有趣的圖形,可以 戳這裡 – Demo
多重 box-shadow 實現立體感
這種方法運用在 text-shadow 上同樣可以,可以實現文字的立體感。
運用多重 box-shadow ,不斷偏移 1px ,就可以產生十分立體的感覺。
運用在按鈕:
運用在文字:
多重 box-shadow 實現任意圖片轉換
嗯,講真~~ 我覺得這個是最有趣的。
多重 box-shadow 還能做什麼呢。由於 box-shadow 的多重性,也就是 無論多少重都可以
,那麼理論上任意一張圖片,每一個像素點都可以由一重 1px*1px 的 box-shadow 來表示。
為了完成這個任務, canvas
剛好提供了一個方法 CanvasRenderingContext2D.getImageData
可以獲取到圖片每一個像素點的 rgba 值,那麼圖片轉為一個完全由 box-shadow 表示的圖片是完全可行的。
為此,我倒騰了許久,寫了這麼一個小插件,可以將任意圖片轉化為由 box-shadow 表示的單個 div 標簽。
如果上面的幾點還有用武之地,那麼這個功能我覺得除了看似厲害之外真的是毫無實用之處,上面也說了,box-shadow 是比較耗性能的,因為即便是一個 100px*100px
的圖形,轉化之後都有 10000
重陰影,無論是對性能還是可讀性而言,都是毀滅性的,但是講真,還是挺有趣的。
box-shadow 就先說這些吧,box-shadow 肯定還要其它的一些妙用,細心之人可以繼續挖掘之。
filter:drop-shadow
其實說到 box-shadow,就不得不提到另一個和它極為相似的 CSS3 新屬性 filter:drop-shadow
,filter 即是 CSS 濾鏡,可以在元素呈現之前,為元素的渲染提供一些效果,如模糊、顏色轉移之類的。濾鏡常用於調整圖像、背景、邊框的渲染。
當然這裡我們只說 filter:drop-shadow。
filter:drop-shadow 也很好玩,本想繼續長篇大論討論下去,無奈發現 張鑫旭
大神兩篇文章已經把我想說的都囊括了,前人栽樹,後人乘涼,我也就不再獻醜了。
兩篇非常值得一讀的文章:
另外 《CSS SECRET》(CSS揭秘)這本大作也對 filter:drop-shadow
有詳細的描述,可以去看看。
希望這篇文章對大家有所幫助,尤其是在對問題解決的思維層面上。
到此本文結束,如果還有什麼疑問或者建議,可以多多交流,寫文章不容易,覺得不錯的希望大家點個推薦。
原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。