各種特殊的陰影
陰影有5個值:
box-shadow: 0 5px 4px -4px black;
瀏覽器創(chuàng)建陰影的大概過程是這樣的:
先創(chuàng)建一個和原有元素大小相同的塊,顏色由最后一個值指定。
接下來由前兩個值指定左偏移和上偏移。
第三個值來給定模糊的大小,你給了4,就意味著在現(xiàn)在塊的邊界向外向里分別模糊4。
第四個值用來在現(xiàn)有的塊的基礎(chǔ)上調(diào)整塊的大小,給-4相當(dāng)于在4個方向上都縮小4。
只有一邊有的陰影
利用上面這些創(chuàng)建只有一邊的陰影就很容易了。假設(shè)創(chuàng)建只有下面有的:
使用最后一個值將陰影縮小到正好被元素覆蓋,在使用上偏移,將其下面的部分露出來。
box-shadow: 0 5px 4px -4px black;
只有相對的兩邊有陰影
啊。。。這個只有使用兩個陰影才能實現(xiàn)了。。。
box-shadow: 5px 0 5px -5px black,
-5px 0 5px -5px black;
不規(guī)則陰影
面對矩形或使用圓角屬性創(chuàng)建出來的圖形的時候,之前的陰影可以很好的起到作用,但是當(dāng)有偽元素或透明背景等會使元素外形不規(guī)則的情形時,之前的陰影就不那么好用了。
這里有一個新的玩意,叫Filter Effects specification。
這個玩意是從SVG里借鑒來的,但是使用上不需要SVG的知識,簡單的函數(shù)就好,比如blur()、grayscale()、drop-shadow()。
這里我們要用到的就是drop-shadow(),接收的參數(shù)和box-shadow差不多,沒有改變大小的那個。
#irregularShadow{
height:100px;
color: deeppink;
border: 10px dashed;
text-shadow: .1em .2em yellow;
-webkit-filter: drop-shadow(.1em .1em .5em rgba(255,255,0,1));
filter: drop-shadow(.05em .05em .1em gray);
}
這個其實是對這個元素中所有不透明的部分應(yīng)用了陰影,這時如果你使用text-shadow,就會多一層陰影哦。
這個陰影非常靈活,基本就意味著這個元素(包括其偽元素)在光照下哪里會有陰影,這里就會在哪里生成陰影。
色彩渲染圖片濾鏡
就是在圖片上添加濾鏡的效果咯。
以前我們使用圖片編輯軟件來編輯出各種不同效果的圖片來達(dá)成目的,但這樣不僅增加了HTTP請求,也使得維護(hù)變得更加困難。
還有一種是通過在圖片上面覆蓋一層透明的覆蓋層,模擬給圖片加上濾鏡的效果,這樣確實可以模擬有限的效果,但是這樣做并不能模擬所有的效果。
使用CSS的Filter和Blending可以很好的達(dá)到效果。
使用JS的canvas可以將圖片轉(zhuǎn)換到畫布中,這樣可以在畫布中獲得對所有點(diǎn)的顏色的完全控制,如果你想編寫自己的濾鏡的算法的話,那這個非常適合,但是如果使用CSS中的Filter和Blending就可以達(dá)到的效果,使用這個方法無論是從速度,開銷還是我們自己的工作量來說都是不劃算的。
Filter
我們可以合并多個filter來達(dá)成我們的效果。而且,這個屬性還可以使用動畫。可以做出炫酷的效果哦。
#filter{
width:200px;
transition: 1s filter, 1s -webkit-filter;
-webkit-filter: sepia() saturate(4) hue-rotate(295deg);
filter: sepia() saturate(4) hue-rotate(295deg);
}
#filter:hover,
#filter:focus {
-webkit-filter: none;
filter: none;
}
Blending
這個就像是PS中的混合,有時filter并不能完全達(dá)到我們想要的效果時我們就可以使用這個。
這個東西在控制頂層的圖層如何與底層的圖層混合,我們將背景色放在背景圖片下,再使用混合來混合這兩個圖層。
#blend{
width:200px;
height:200px;
background-size: cover;
background-position: center;
background-color: hsl(335, 100%, 50%);
background-blend-mode: luminosity;
transition: .5s background-color;
background-image: url("../img/tiger.jpg");
}
#blend:hover {
background-color: transparent;
}
毛玻璃效果
在背景很復(fù)雜的情況下,我們需要呈現(xiàn)文字的時候就需要在文字下面一個半透明的底。
但有時半透明的底也還是不夠,我們想?yún)⒄誱acOS那樣將背景高斯模糊一下。
我們當(dāng)然不能在本元素上進(jìn)行高斯模糊,這樣內(nèi)容也會被模糊,那么我們就使用偽元素吧。
對于背景元素,我們就簡單的設(shè)置下背景圖片,這里有一點(diǎn)是要注意的,首先一定要創(chuàng)建一個不為auto且不為負(fù)的z軸放置上下文,這個一會兒解釋。
#blur {
position: relative;
padding:20px;
height:400px;
background: url("../img/tiger.jpg") 0/cover fixed;
z-index: 1;
}
里面放置文字內(nèi)容的元素放一個半透明的背景,偽元素模糊過的背景將放在這個半透明背景的下面。這里的z軸放置上下文一定要為默認(rèn)值auto。
#blur .content{
position: relative;
max-width:400px;
margin:0 auto;
border-radius: 20px;
padding:20px;
background: hsla(0,0%,100%,.3);
overflow: hidden;
font: normal 22px/40px serif;
}
偽元素:
#blur .content:before{
content: '';
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
-webkit-filter: blur(20px);
filter: blur(20px);
background: url("../img/tiger.jpg") 0/cover fixed;
z-index: -1;
margin: -30px;
}
偽元素這里要說的比較多。
首先,我們這里是放一個偽裝的圖片用來模糊,所以這張圖片顯示的位置一定要保證和大背景位置相同才行,這里使用的是fixed的背景位置,如果你不喜歡使用別的也沒問題,能保證位置一致就好。
其次,之前創(chuàng)建的z軸上下文在這里就用到了,我們想要的效果是將被模糊的偽裝圖片放在偽元素的父元素(在這里就是其生成元素)的透明背景的下面,但是要放在其父元素的父元素(真正背景所在元素)的背景的上面。
z-index: -1會使這個偽元素放到其z軸上下文的背景前,內(nèi)容下面。在這里#blur創(chuàng)建了z軸上下文,.content因為還是默認(rèn)值auto,所以沒有創(chuàng)建。那么這個偽元素就理所當(dāng)然的放在了我們想放的地方。
最后,因為模糊在邊緣部分是有漸變的,模糊的半徑會越來越小直至為0,我們不想要這樣的效果,我們想要的是清晰的邊界。那么margin: -30px就起到了這個作用,再配合其父元素的overflow:hidden,我們就將這部分漸變隱藏起來了。
折角效果
以前的實現(xiàn)是添加兩個偽元素一個用來遮蓋元素的一角,一個用來模仿折過來的角。
這樣的解決方法不夠靈活,有更靈活的嘛?
45度時的方案
首先利用線性漸變創(chuàng)建一個切角的元素。
#folded-corner{
width:200px;
height:200px;
background: #58a; /* Fallback */
background:
linear-gradient(-135deg, transparent 2em, #58a 0);
}
然后我們再用線性漸變創(chuàng)建一個小小的矩形背景,這個矩形的對角線正好與切角的那條邊重合,矩形的左下半部分作為折過去的角,右上半部分保持透明就好。
#folded-corner{
width:200px;
height:200px;
background: #58a; /* Fallback */
background:
linear-gradient(-135deg,transparent 50%, rgba(0,0,0,.4) 0) no-repeat 100% 0 / 2em 2em,
linear-gradient(-135deg, transparent 1.5em, #58a 0);
}
其他角度
其他角度可就不像45度這么簡單咯。。。
首先你得計算好。。。其次這回折過來的角其實應(yīng)該是反著的,用一個矩形小背景的辦法行不通了,得用偽元素了。
我們首先來搞定形狀的問題:
我們需要根據(jù)切角的角度和大小來計算偽元素的長寬。這里使用scss將會有很大的優(yōu)勢。
@mixin folded-corner($background, $size, $angle: 30deg) {
$x: $size / sin($angle);
$y: $size / cos($angle);
&::before {
content: '';
position: absolute;
top: 0; right: 0;
width: $x; height: $y;
background: linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.4) 0)
100% 0 no-repeat;
}
}
這時乍一看是完成了,但你找個真正的紙折一下就會發(fā)現(xiàn),其實并不對。。。
偽元素還需要旋轉(zhuǎn)一定的角度才行。
最后就是這樣咯:
@mixin folded-corner($background, $size, $angle: 30deg) {
position: relative;
background: $background; /* Fallback */
background:
linear-gradient($angle - 180deg,
transparent $size, $background 0);
border-radius: .5em;
$x: $size / sin($angle);
$y: $size / cos($angle);
&::before {
content: '';
position: absolute;
top: 0; right: 0;
background: linear-gradient(to left bottom,
transparent 50%, rgba(0,0,0,.2) 0,
rgba(0,0,0,.4)) 100% 0 no-repeat;
width: $y; height: $x;
transform: translateY($y - $x)
rotate(2*$angle - 90deg);
transform-origin: bottom right;
border-bottom-left-radius: inherit;
box-shadow: -.2em .2em .3em -.1em rgba(0,0,0,.2);
}
}