關於 CSS 陰影,以前已經有寫過一篇,box-shadow 與 filter:drop-shadow 詳解及奇技淫巧,介紹了一些關於 box-shadow
的用法。css
最近一個新的項目,CSS-Inspiration,挖掘了其餘不少有關 CSS 陰影的點子,是以前的文章沒有覆蓋到的新內容,並且有一些頗有意思,遂打算再起一篇。html
本文的題目是 CSS 陰影技巧與細節。CSS 陰影,卻不必定是 box-shadow
與 filter:drop-shadow
,爲啥?由於使用其餘屬性也能夠模擬陰影,並且是各類各樣的陰影。下面且聽我娓娓道來~ git
先說單側投影,關於 box-shadow
,大部分時候,咱們使用它都是用來生成一個兩側的投影,或者一個四側的投影。以下:github
OK,那若是要生成一個單側的投影呢?sass
咱們來看看 box-shadow 的用法定義:函數
{
box-shadow: none | [inset? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? <color>? ] ]#
}
複製代碼
以 box-shadow: 1px 2px 3px 4px #333
爲例,4 個數值的含義分別是,x 方向偏移值、y 方向偏移值 、模糊半徑、擴張半徑。動畫
這裏有一個小技巧,擴張半徑能夠爲負值。ui
繼續,若是陰影的模糊半徑,與負的擴張半徑一致,那麼咱們將看不到任何陰影,由於生成的陰影將被包含在原來的元素之下,除非給它設定一個方向的偏移量。因此這個時候,咱們給定一個方向的偏移值,便可實現單側投影:url
接着上面的說。
很明顯,0 = -0
,因此當 box-shadow
的模糊半徑和擴張半徑都爲 0 的時候,咱們也能夠獲得一個和元素大小同樣的陰影,只不過被元素自己遮擋住了,咱們嘗試將其偏移出來。
CSS代碼以下:
div {
width: 80px;
height: 80px;
border: 1px solid #333;
box-sizing: border-box;
box-shadow: 80px 80px 0 0 #000;
}
複製代碼
獲得以下結果:
有什麼用呢?好像沒什麼意義啊。
額,確實好像沒什麼用。不過咱們注意到,box-shadow
是能夠設置多層的,也就是多層陰影,並且能夠進行過渡變換動畫(補間動畫)。可是 background-image: linear-gradient()
,也就是漸變背景是不能進行補間動畫的。
這又扯到哪裏去了。好咱們回來,利用上面的特性,咱們能夠利用 box-shadow
實現本來只能利用漸變才能實現的背景圖:
用 box-shadow
,實現它的 CSS 代碼以下(能夠更簡化):
.shadow {
position: relative;
width: 250px;
height: 250px;
}
.shadow::before {
content: "";
position: absolute;
width: 50px;
height: 50px;
top: -50px;
left: -50px;
box-shadow:
50px 50px #000, 150px 50px #000, 250px 50px #000,
50px 100px #000, 150px 100px #000, 250px 100px #000,
50px 150px #000, 150px 150px #000, 250px 150px #000,
50px 200px #000, 150px 200px #000, 250px 200px #000,
50px 250px #000, 150px 250px #000, 250px 250px #000;
}
複製代碼
用漸變來實現的話,只須要這樣:
.gradient {
width: 250px;
height: 250px;
background-image: linear-gradient(90deg, #000 0%, #000 50%, #fff 50%, #fff 100%);
background-size: 100px 100px;
}
複製代碼
爲何選擇更爲複雜的 box-shadow
呢?由於它能夠進行補間動畫,像這樣,這是使用漸變作不到的:
CodePen Demo -- box-shadow實現背景動畫
固然,這只是個示例 Demo,運用點想象力還有不少有意思的效果,再貼一個:
CodePen Demo -- CSS Checker Illusion( By David Khourshid )
嗯,頗有意思,就是實際用途可能不大。
好,咱們繼續。下一個主題是立體投影。
這個說法很奇怪,陰影的出現,本就是爲了讓本來的元素看起來更加的立體,那這裏所謂的立體投影,是個怎麼立體法?
這裏所謂的立體投影,並不必定是使用了 box-shadow
、text-shadow
或者 drop-shadow
,而是咱們使用其餘元素或者屬性模擬元素的陰影。而這樣作的目的,是爲了可以突破 box-shadow
這類元素的一些定位侷限。讓陰影的位置、大小、模糊度能夠更加的靈活。
OK,讓咱們來看看,這樣一個元素,咱們但願經過自定義陰影的位置,讓它更加立體:
上圖 div 只是帶了一個很是淺的 box-shadow
,看上去和立體沒什麼關係,接下來,咱們經過 div 的僞元素,給它生成一個和原圖邊角形狀相似的圖形,再經過 transform 位移一下,多是這樣:
OK,最後對這個用僞元素生成的元素進行一些虛化效果(filter或者box-shadow均可以),就能夠實現一個邊角看起來像被撕開的立體效果:
代碼很是簡單,僞 CSS 代碼示意以下:
div {
position: relative;
width: 600px;
height: 100px;
background: hsl(48, 100%, 50%);
border-radius: 20px;
}
div::before {
content: "";
position: absolute;
top: 50%;
left: 5%;
right: 5%;
bottom: 0;
border-radius: 10px;
background: hsl(48, 100%, 20%);
transform: translate(0, -15%) rotate(-4deg);
transform-origin: center center;
box-shadow: 0 0 20px 15px hsl(48, 100%, 20%);
}
複製代碼
因此總結一下:
還有其餘不少場景:
上面的立體效果在文字上就徹底不適用了,因此對待文字的立體陰影效果,還須要另闢蹊徑。
正常而言,咱們使用 text-shadow 來生成文字陰影,像這樣:
<div> Txt Shadow</div>
-----
div {
text-shadow: 6px 6px 3px hsla(14, 100%, 30%, 1);
}
複製代碼
嗯,挺好的,就是不夠立體。那麼要作到立體文字陰影,最多見的方法就是使用多層文字陰影疊加。
Tips:和
box-shadow
同樣,text-shadow
是能夠疊加多層的!可是對於單個元素而言,drop-shadow
的話就只能是一層。
好,上面的文字,咱們試着疊加個 50 層文字陰影試一下。額,50 層手寫,其實很快的~
好吧,手寫真的太慢了,還容易出錯,因此這裏咱們須要藉助一下 SASS/LESS 幫忙,寫一個生成 50 層陰影的 function
就好,咱們每向右和向下偏移 1px,生成一層 text-shadow:
@function makeLongShadow($color) {
$val: 0px 0px $color;
@for $i from 1 through 50 {
$val: #{$val}, #{$i}px #{$i}px #{$color};
}
@return $val;
}
div {
text-shadow: makeLongShadow(hsl(14, 100%, 30%));
}
複製代碼
上面的 SCSS 代碼。通過編譯後,就會生成以下 CSS:
div {
text-shadow: 0px 0px #992400, 1px 1px #992400, 2px 2px #992400, 3px 3px #992400, 4px 4px #992400, 5px 5px #992400, 6px 6px #992400, 7px 7px #992400, 8px 8px #992400, 9px 9px #992400, 10px 10px #992400, 11px 11px #992400, 12px 12px #992400, 13px 13px #992400, 14px 14px #992400, 15px 15px #992400, 16px 16px #992400, 17px 17px #992400, 18px 18px #992400, 19px 19px #992400, 20px 20px #992400, 21px 21px #992400, 22px 22px #992400, 23px 23px #992400, 24px 24px #992400, 25px 25px #992400, 26px 26px #992400, 27px 27px #992400, 28px 28px #992400, 29px 29px #992400, 30px 30px #992400, 31px 31px #992400, 32px 32px #992400, 33px 33px #992400, 34px 34px #992400, 35px 35px #992400, 36px 36px #992400, 37px 37px #992400, 38px 38px #992400, 39px 39px #992400, 40px 40px #992400, 41px 41px #992400, 42px 42px #992400, 43px 43px #992400, 44px 44px #992400, 45px 45px #992400, 46px 46px #992400, 47px 47px #992400, 48px 48px #992400, 49px 49px #992400, 50px 50px #992400;
}
複製代碼
看看效果:
額,很不錯,很立體。可是,就是醜,並且說不上來的奇怪。
問題出在哪裏呢,陰影實際上是存在明暗度和透明度的變化的,因此,對於漸進的每一層文字陰影,明暗度和透明度應該都是不斷變化的。這個需求,SASS 能夠很好的實現,下面是兩個 SASS 顏色函數:
fade-out
改變顏色的透明度,讓顏色更加透明desaturate
改變顏色的飽和度值,讓顏色更少的飽和關於 SASS 顏色函數,能夠看看這裏:Sass基礎—顏色函數
咱們使用上面兩個 SASS 顏色函數修改一下咱們的 CSS 代碼,主要是修改上面的 makeLongShadow
function 函數:
@function makelongrightshadow($color) {
$val: 0px 0px $color;
@for $i from 1 through 50 {
$color: fade-out(desaturate($color, 1%), .02);
$val: #{$val}, #{$i}px #{$i}px #{$color};
}
@return $val;
}
複製代碼
好,看看最終效果:
嗯,大功告成,此次順眼了不少~
固然,使用 CSS 生成立體文字陰影的方法還有不少,下面再貼出一例,使用了透明色疊加底色的多重線性漸變實現的文字立體陰影,感興趣的同窗能夠去看看具體實現:
上面提到了經過多層陰影疊加實現文字的立體陰影。運用在 div 這些容器上也是能夠的。固然這裏還有一種挺有意思的方法。假設咱們,有一個矩形元素,但願給他添加一個長投影,像下面這樣:
要生成這種長投影,剛剛說的疊加多層陰影能夠,再就是藉助元素的兩個僞元素,其實上面的圖是這樣的:
關鍵點在於,咱們經過對兩個僞元素的 transform: skew()
變換以及從實色到透明色的背景色變化,實現了長投影的效果:
一般而言,咱們生成陰影的方式大可能是 box-shadow
、filter: drop-shadow()
、text-shadow
。可是,使用它們生成的陰影一般只能是單色或者同色系的。
你這麼說,難道還能夠生成漸變色的陰影不成?
額,固然不行。
這個真不行,可是經過巧妙的利用 filter: blur
模糊濾鏡,咱們能夠僞裝生成漸變色或者說是顏色豐富的陰影效果。
假設咱們有下述這樣一張頭像圖片:
下面就利用濾鏡,給它添加一層與原圖顏色相仿的陰影效果,核心 CSS 代碼以下:
.avator {
position: relative;
background: url($img) no-repeat center center;
background-size: 100% 100%;
&::after {
content: "";
position: absolute;
top: 10%;
width: 100%;
height: 100%;
background: inherit;
background-size: 100% 100%;
filter: blur(10px) brightness(80%) opacity(.8);
z-index: -1;
}
}
複製代碼
看看效果:
其簡單的原理就是,利用僞元素,生成一個與原圖同樣大小的新圖疊加在原圖之下,而後利用濾鏡模糊 filter: blur()
配合其餘的亮度/對比度,透明度等濾鏡,製做出一個虛幻的影子,假裝成原圖的陰影效果。
嗯,最重要的就是這一句 filter: blur(10px) brightness(80%) opacity(.8);
。
CodePen Demo -- filter create shadow
好,上文主要是一些實現各類陰影的方法,接下來是效果篇。先來看看使用 box-shadow
實現的一些燈光效果。
這個效果也叫 Neon,Codepen 上有不少相似的效果,本質上都是大範圍的 box-shadow
過渡效果與白色文字的疊加:
CodePen Demo -- box-shadow實現霓虹氖燈文字效果
和上面的效果相似,本質上都是多重陰影的過渡效果,或許再來點 3D 效果?
合理搭配,效果更佳:
CodePen Demo -- 使用box-shadow實現陰影燈光show
嗯哼,既然標題叫你所不知道的 CSS 陰影技巧與細節,那麼本文也應該有一點奇技淫巧。
先來看這個,單個標籤實現仿抖音 LOGO,固然因爲限定在一個元素,因此細節方面仍是有不少瑕疵。
想着仿的原因是某天刷抖音的時候看見這個 LOGO 的一時興起,CSS 寫多了,看見什麼東西都會條件反射的想這個能不能用 CSS 實現。
咱們先來看看抖音的 LOGO:
其實很簡單,主體實際上是由3個顏色不一樣相似 J 的形狀組成。而單獨拎出一個,又能夠把它分紅四分之三圓、|以及㇏組成。
正好,一個元素加上它的兩個僞元素,恰好能夠湊成這三個形狀,咱們試着實現如下,簡單 CSS 代碼以下:
<div></div>
---
div {
position: relative;
width: 37px;
height: 218px;
background: #fff;
&::before {
content: "";
position: absolute;
width: 100px;
height: 100px;
border: 37px solid #fff;
border-top: 37px solid transparent;
border-radius: 50%;
top: 123px;
left: -137px;
transform: rotate(45deg);
}
&::after {
content: "";
position: absolute;
width: 140px;
height: 140px;
border: 30px solid #fff;
border-right: 30px solid transparent;
border-top: 30px solid transparent;
border-left: 30px solid transparent;
top: -100px;
right: -172px;
border-radius: 100%;
transform: rotate(45deg);
}
}
複製代碼
上面的代碼就能夠生成整個形狀的主體:
接下來就是輪到 filter: drop-shadow()
登場,它能夠在元素呈現以前,爲元素的渲染提供一些效果,最多見的也就用它渲染總體陰影。咱們一般會用它來實現對話框的小三角與整個對話框的陰影效果,像下面這樣,左邊是使用 drop-shadow
的效果,右邊是使用普通 box-shadow
的效果。
本文假定讀者已經瞭解了 drop-shadow 的基本用法,上圖效果來自這裏:CodePen Demo -- Drop-shadow vs box-shadow (2) By Kseso
OK,回到咱們正文,下面咱們使用 filter: drop-shadow()
生成它的第一層左邊的藍色陰影,添加在主體 div:
div {
position: relative;
width: 37px;
height: 218px;
background: #fff;
filter:drop-shadow(-10px -10px 0 #24f6f0);
&::before,
&::after {
...
}
}
複製代碼
獲得以下效果:
好,接下來咱們只須要再添加一層紅色 filter: drop-shadow()
在右側就大功告成!
等等!哪裏不對,上面我也有提到過, 和 box-shadow
同樣,text-shadow
是能夠疊加多層的!可是對於單個元素而言, drop-shadow
的話就只能是一層。
也就是說,沒法在 div 上再使用 filter: drop-shadow()
生成另外一側的紅色投影,不過還好,咱們還有兩個僞元素的filter: drop-shadow()
以及 box-shadow
尚未用上,通過一番嘗試:
div {
position: relative;
width: 37px;
height: 218px;
background: #fff;
filter:drop-shadow(-10px -10px 0 #24f6f0) contrast(150%) brightness(110%);
box-shadow: 11.6px 10px 0 0 #fe2d52;
&::before {
....
filter: drop-shadow(16px 0px 0 #fe2d52);
}
&::after {
....
filter:drop-shadow(14px 0 0 #fe2d52);
}
}
複製代碼
咱們分別再利用 div 的 box-shadow
以及兩個僞元素的 filter: drop-shadow()
,在單個標籤的限制下,最終結果以下:
總結一下:
關於上述抖音 LOGO,經友人提醒,其實應該只是兩個類 J 形的形狀重疊在一塊兒,重疊部分爲白色,非重疊部分爲各自原色。
當初想複雜了,這個效果我嘗試了一下,使用 CSS 的混合模式 mix-blend-mode
也是能夠實現的,下面給出實現方法以下,感興趣的同窗能夠看看:
CodePen Demo -- 使用 mix-blend-mode 實現抖音 LOGO
固然,關於 CSS 陰影還有不少有意思的技巧和細節,本文限於篇幅再也不一一羅列。
我在 Git 上開了個倉庫,CSS-Inspiration,以分類的形式,展現不一樣 CSS 屬性或者不一樣的課題使用 CSS 來解決的各類方法。更多有意思的 CSS 技巧能夠在這裏找到,並且是每日更新。
感謝耐心讀完。更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。
好了,本文到此結束,但願對你有幫助 :)
若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。