關於 CSS 陰影,以前已經有寫過一篇,box-shadow 與 filter:drop-shadow 詳解及奇技淫巧,介紹了一些關於 box-shadow
的用法。javascript
最近一個新的項目,CSS-Inspiration,挖掘了其餘不少有關 CSS 陰影的點子,是以前的文章沒有覆蓋到的新內容,並且有一些頗有意思,遂打算再起一篇。php
本文的題目是 CSS 陰影技巧與細節。CSS 陰影,卻不必定是 box-shadow
與 filter:drop-shadow
,爲啥?由於使用其餘屬性也能夠模擬陰影,並且是各類各樣的陰影。下面且聽我娓娓道來~css
單側投影
先說單側投影,關於 box-shadow
,大部分時候,咱們使用它都是用來生成一個兩側的投影,或者一個四側的投影。以下:html
OK,那若是要生成一個單側的投影呢?前端
咱們來看看 box-shadow 的用法定義:java
1
2
3
|
{
box-shadow:
none
| [
inset
? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? <color>? ] ]#
}
|
以 box-shadow: 1px 2px 3px 4px #333
爲例,4 個數值的含義分別是,x 方向偏移值、y 方向偏移值 、模糊半徑、擴張半徑。react
這裏有一個小技巧,擴張半徑能夠爲負值。css3
繼續,若是陰影的模糊半徑,與負的擴張半徑一致,那麼咱們將看不到任何陰影,由於生成的陰影將被包含在原來的元素之下,除非給它設定一個方向的偏移量。因此這個時候,咱們給定一個方向的偏移值,便可實現單側投影:git
CodePen Demo -- css單側投影github
投影背景 / 背景動畫
接着上面的說。
很明顯,0 = -0
,因此當 box-shadow
的模糊半徑和擴張半徑都爲 0 的時候,咱們也能夠獲得一個和元素大小同樣的陰影,只不過被元素自己遮擋住了,咱們嘗試將其偏移出來。
CSS代碼以下:
1
2
3
4
5
6
7
|
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 代碼以下(能夠更簡化):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
.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
;
}
|
用漸變來實現的話,只須要這樣:
1
2
3
4
5
6
|
.gradient {
width
:
250px
;
height
:
250px
;
background-image
: linear-gradient(
90
deg,
#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 只是帶了一個很是淺的 bos-shadow
,看上去和立體沒什麼關係,接下來,咱們經過 div 的僞元素,給它生成一個和原圖邊角形狀相似的圖形,再經過 transform 位移一下,多是這樣:
OK,最後對這個用僞元素生成的元素進行一些虛化效果(filter或者box-shadow均可以),就能夠實現一個邊角看起來像被撕開的立體效果:
代碼很是簡單,僞 CSS 代碼示意以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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(
-4
deg);
transform-origin:
center
center
;
box-shadow:
0
0
20px
15px
hsl(
48
,
100%
,
20%
);
}
|
因此總結一下:
- 立體投影的關鍵點在於利於僞元素生成一個大小與父元素相近的元素,而後對其進行 rotate 以及定位到合適位置,再賦於陰影操做
- 顏色的運用也很重要,陰影的顏色一般比自己顏色要更深,這裏使用 hsl 表示顏色更容易操做,l 控制顏色的明暗度
還有其餘不少場景:
文字立體投影 / 文字長陰影
上面的立體效果在文字上就徹底不適用了,因此對待文字的立體陰影效果,還須要另闢蹊徑。
正常而言,咱們使用 text-shadow 來生成文字陰影,像這樣:
1
2
3
4
5
|
<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:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@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:
1
2
3
|
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 函數:
1
2
3
4
5
6
7
8
9
10
|
@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 代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
.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 實現的燈光效果
好,上文主要是一些實現各類陰影的方法,接下來是效果篇。先來看看使用 box-shadow
實現的一些燈光效果。
box-shadow 實現霓虹氖燈文字效果
這個效果也叫 Neon,Codepen 上有不少相似的效果,本質上都是大範圍的 box-shadow
過渡效果與白色文字的疊加:
CodePen Demo -- box-shadow實現霓虹氖燈文字效果
使用box-shadow實現陰影燈光show
和上面的效果相似,本質上都是多重陰影的過渡效果,或許再來點 3D 效果?
合理搭配,效果更佳:
CodePen Demo -- 使用box-shadow實現陰影燈光show
使用 drop-shadow | box-shadow 實現單標籤抖音 LOGO
嗯哼,既然標題叫你所不知道的 CSS 陰影技巧與細節,那麼本文也應該有一點奇技淫巧。
先來看這個,單個標籤實現仿抖音 LOGO,固然因爲限定在一個元素,因此細節方面仍是有不少瑕疵。
想着仿的原因是某天刷抖音的時候看見這個 LOGO 的一時興起,CSS 寫多了,看見什麼東西都會條件反射的想這個能不能用 CSS 實現。
咱們先來看看抖音的 LOGO:
其實很簡單,主體實際上是由3個顏色不一樣相似 J 的形狀組成。而單獨拎出一個,又能夠把它分紅四分之三圓、|以及㇏組成。
正好,一個元素加上它的兩個僞元素,恰好能夠湊成這三個形狀,咱們試着實現如下,簡單 CSS 代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<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(
45
deg);
}
&::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(
45
deg);
}
}
|
接下來就是輪到 filter: drop-shadow()
登場,它能夠在元素呈現以前,爲元素的渲染提供一些效果,最多見的也就用它渲染總體陰影。咱們一般會用它來實現對話框的小三角與整個對話框的陰影效果,像下面這樣,左邊是使用 drop-shadow
的效果,右邊是使用普通 box-shadow
的效果。
本文假定讀者已經瞭解了 drop-shadow 的基本用法,上圖效果來自這裏:CodePen Demo -- Drop-shadow vs box-shadow (2) By Kseso
OK,回到咱們正文,下面咱們使用 filter: drop-shadow()
生成它的第一層左邊的藍色陰影,添加在主體 div:
1
2
3
4
5
6
7
8
9
10
11
12
|
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
尚未用上,通過一番嘗試:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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()
,在單個標籤的限制下,最終結果以下:
總結一下:
- 主要藉助了兩個僞元素實現了總體結構,藉助了 drop-shadow 生成一層總體陰影
- drop-shadow 只能是單層陰影,因此另外一層陰影須要多嘗試
- contrast(150%) brightness(110%) 則能夠加強圖像的對比度和亮度,更貼近抖音LOGO的效果
固然,關於 CSS 陰影還有不少有意思的技巧和細節,本文限於篇幅再也不一一羅列。
我在 Git 上開了個倉庫,CSS-Inspiration,以分類的形式,展現不一樣 CSS 屬性或者不一樣的課題使用 CSS 來解決的各類方法。更多有意思的 CSS 技巧能夠在這裏找到,並且是每日更新。
最後
感謝耐心讀完。更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。
好了,本文到此結束,但願對你有幫助 :)
若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。