百度前端技術(shù)學(xué)院2017于2月24日開(kāi)始進(jìn)行,一共有6個(gè)學(xué)院可供學(xué)習(xí),分別是小薇學(xué)院(html/css基礎(chǔ))、斌斌學(xué)院(js基礎(chǔ))、耀耀學(xué)院(小游戲/交互)、商業(yè)平臺(tái)學(xué)院(web/ios/android)、ECharts & WebVR學(xué)院(VR相關(guān))和糯米學(xué)院(css3/vue等),從百度前端技術(shù)學(xué)院今年推出的各學(xué)院任務(wù)看來(lái),目前互聯(lián)網(wǎng)行業(yè)對(duì)從事前端行業(yè)的程序員要求越發(fā)高了。任重而道遠(yuǎn),努力吧。
《有趣的鼠標(biāo)懸浮模糊效果》作為糯米學(xué)院中的進(jìn)階任務(wù),目的主要是讓學(xué)院通過(guò)完成任務(wù),掌握transition、transform、@keyframes等屬性的使用,從任務(wù)的標(biāo)簽“CSS3、動(dòng)畫(huà)、過(guò)渡、效果”也能看出其主旨。經(jīng)過(guò)3天的努力,終于把這個(gè)任務(wù)完成了,通過(guò)連續(xù)不斷的發(fā)現(xiàn)bug、解bug,不僅對(duì)很多屬性進(jìn)行使用,也越來(lái)越有一套獨(dú)自解決問(wèn)題的辦法。以下是總結(jié)。
任務(wù)分解:該任務(wù)要達(dá)到的效果是,當(dāng)鼠標(biāo)懸浮在按鈕上方時(shí),按鈕上的文字由透明到上浮淡出,文字上有的顏色有流光漸變效果,按鈕的邊框從上、右、下、左四邊的中間出現(xiàn)并向兩端擴(kuò)展至銜接在一起,按鈕的背景由清晰變?yōu)槟:t按以上要求,可以將這個(gè)大的任務(wù)分解為四個(gè)小任務(wù):
1.文字的上浮淡出效果;
2.文字顏色的流光漸變效果;
3.按鈕邊框的中間向兩端擴(kuò)展效果;
4.背景的模糊效果
打完上面這四個(gè)小怪獸,這個(gè)任務(wù)也就基本被解決了??偨Y(jié)下來(lái),我用了這些技能打怪獸:
1.4個(gè)效果都使用到偽類(lèi):hover;
2.“邊框擴(kuò)展”、“背景模糊”使用了偽元素::before、::after;
3.“文字上浮淡出、“邊框擴(kuò)展”、“背景模糊”都用到了transition屬性;
4.“文字流光漸變”使用了@keyframes系列屬性、以及chrome瀏覽器支持的-webkit-background-clip、-webkit-text-fill-color、-webkit-linear-gradient;
5.“背景模糊”使用了filter屬性及其值blur();
6.“邊框擴(kuò)展”使用了transform屬性及其值scale3d()、rotate(),使用了transform-origin屬性。
以下是單個(gè)按鈕html結(jié)構(gòu)代碼:
<article>
<figure>
<div id="left-right1">
<div id="top-bottom1">
<a >“小星的博客|Small Star's Blog”</a>
</div>
</div>
</figure>
</article>
其中,figure元素用于放背景,也用于實(shí)現(xiàn)背景模糊效果;兩個(gè)div層主要用于產(chǎn)生偽元素,模仿邊框;a元素用于實(shí)現(xiàn)文字的上浮淡出。figure元素的寬高要大于子元素,兩個(gè)div層和a元素的寬高相同。該結(jié)構(gòu)是可以?xún)?yōu)化的:
1.可以使用a元素產(chǎn)生偽元素,但使用a元素產(chǎn)生deep偽元素模仿邊框擴(kuò)展的時(shí)候,必須給偽元素另加過(guò)渡效果來(lái)抵消a元素實(shí)現(xiàn)文字上浮淡出時(shí)產(chǎn)生的移動(dòng);
2.實(shí)現(xiàn)邊框擴(kuò)展時(shí)用了兩種方法,其中一種要使用4個(gè)偽元素,另一種使用到2個(gè)偽元素,使用2個(gè)偽元素的方法只需一個(gè)div層即可。
以下是構(gòu)建按鈕結(jié)構(gòu)的css代碼:
article{
float:left;
width:100%;
height:500px;
}
figure{
position:relative;
width:400px;
height:180px;
margin:0 0 0 50%;
top:160px;
left:-200px;
box-sizing:border-box;
background:url(../img/button-bg.jpg);
border-radius:5px;
}
figure>div{
position:relative;
width:320px;
height:120px;
top:30px;
left:40px;
box-sizing:border-box;
}
div>div{
position:relative;
width:320px;
height:120px;
}
div>a{
display:block;
position: relative;
text-align:center;
line-height:120px;
}
按鈕樣式如下:

4個(gè)效果的實(shí)現(xiàn)及屬性的使用如下:
1.文字的上浮淡出:
實(shí)現(xiàn)原理:在鼠標(biāo)未懸浮在按鈕上時(shí),設(shè)置a元素下移一段距離(top:14px),文字透明(opacity:0);在鼠標(biāo)懸浮時(shí),a元素回到正常位置(top:0),文字不再透明(opacity:1)。屬性值的變化使用transition過(guò)渡,即可達(dá)到平滑變化效果。效果請(qǐng)見(jiàn)文末demo鏈接,代碼如下:
div>a{
top:14px;
opacity:0;
-webkit-transition:opacity 0.3s linear,top 0.3s linear;
transition:opacity 0.3s linear,top 0.3s linear;
}
figure:hover a{
top:0;
opacity:1;
}
2.文字顏色流光漸變效果:
實(shí)現(xiàn)原理:目前沒(méi)有特定的css屬性達(dá)到這樣的效果,只能使用其他屬性組合來(lái)達(dá)到這樣的效果。簡(jiǎn)單來(lái)說(shuō),是將文字鏤空,使其顯示其背景,然后對(duì)背景使用從左至右的顏色漸變,再在鼠標(biāo)懸浮時(shí),對(duì)背景進(jìn)行移動(dòng)來(lái)模仿流光漸變。具體來(lái)說(shuō),以“-webkit-background-clip:text;-webkit-text-fill-color:transparent;”來(lái)進(jìn)行文字鏤空(前者裁剪掉文字內(nèi)容之外的背景,后者將文字填充色設(shè)為透明),以“background-image:-webkit-linear-gradient()”來(lái)實(shí)現(xiàn)背景顏色漸變,最后使用@keyframes來(lái)進(jìn)行背景平移的無(wú)限循環(huán)以模仿流動(dòng)。
在此,需要注意的是,要做到平移結(jié)束與平移開(kāi)始之間的銜接平滑:一是必須設(shè)置平移速度為勻速(linear);還有就是在結(jié)束和開(kāi)始那一瞬間,背景顏色漸變的樣式相同,對(duì)此,可以通過(guò)設(shè)置顏色漸變?yōu)椤?% x色”-“25% y色”-“50% x色”-“75% y色”-“100% x色”,在將背景拉長(zhǎng)至200%來(lái)實(shí)現(xiàn)。
效果請(qǐng)見(jiàn)文末demo鏈接,代碼如下:
div>a{
-webkit-background-clip:text;
-webkit-text-fill-color:transparent;
background-image:-webkit-linear-gradient(left,yellow,green 25%,yellow 50%,green 75%,yellow 100%);
background-size:200% 100%;
}
@keyframes gradient{
from{background-position:0% 0%;}
to{background-position:-100% 0%;}
}
figure:hover a{
animation:gradient 3s linear infinite;
}
3.背景模糊效果:
即毛玻璃效果,實(shí)現(xiàn)原理:在背景所在的元素上使用偽元素,使偽元素寬高、位置完全與背景所在元素相同,再將元素背景設(shè)置為偽元素的背景,對(duì)偽元素使用“filter:blur()”即可。同上,使用transition來(lái)達(dá)到平滑過(guò)渡。效果請(qǐng)見(jiàn)文末demo鏈接,代碼如下:
figure::before{
content:'';
position:absolute;
top:0;
right:0;
bottom:0;
left:0;
background:url(../img/button-bg.jpg);
border-radius:5px;
-webkit-transition:filter 0.3s linear;
transition:filter 0.3s linear;
}
figure:hover::before{
filter:blur(5px);
}
4.邊框擴(kuò)展:
?。?)方法一:使用4個(gè)偽元素來(lái)模仿4個(gè)邊框,通過(guò)在鼠標(biāo)懸浮與否時(shí)使用transform的3D縮放(scale3d())來(lái)達(dá)到效果。需要注意的是,在使用3D縮放時(shí),是應(yīng)該設(shè)置縮放原點(diǎn)的(transform-origin),由于默認(rèn)的縮放原點(diǎn)為元素幾何中點(diǎn),與邊框擴(kuò)展所要求的位置剛好相同,所以在本處可以不設(shè)定該屬性。效果請(qǐng)見(jiàn)文末demo鏈接,代碼及注釋如下:
/*2-5-1.使用scale3d實(shí)現(xiàn)邊框擴(kuò)展*/
/*2-5-1-1.構(gòu)建偽元素*/
#left-right1::before,
#left-right1::after,
#top-bottom1::before,
#top-bottom1::after{
content:'';
position:absolute;
background:#ffffff;
-webkit-transition:-webkit-transform 0.3s;
transition:transform 0.3s;
-webkit-transition-timing-function:cubic-bezier(0.44, 0.05, 0.55, 0.95);
transition-timing-function:cubic-bezier(0.44, 0.05, 0.55, 0.95);/*貝塞爾曲線(xiàn)*/
}
/*2-5-1-2.左右邊框構(gòu)建*/
#left-right1::before,
#left-right1::after{
width:2px;
height:100%;
top:0;
-webkit-transform: scale3d(0.1, 0, 1);
transform: scale3d(0.1, 0, 1);
}
#left-right1::before{
left:0;
}
#left-right1::after{
right:0;
}
/*2-5-1-3.上下邊框構(gòu)建*/
#top-bottom1::before,
#top-bottom1::after{
width:100%;
height:2px;
left:0;
-webkit-transform: scale3d(0, 0.1, 1);
transform: scale3d(0, 0.1, 1);
}
#top-bottom1::before{
top:0;
}
#top-bottom1::after{
bottom:0;
}
/*2-5-1-4.使用偽類(lèi)*/
figure:hover #left-right1::before,
figure:hover #left-right1::after,
figure:hover #top-bottom1::before,
figure:hover #top-bottom1::after{
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
對(duì)方法一的實(shí)現(xiàn)效果,如果仔細(xì)觀察是可以發(fā)現(xiàn)與方法二(見(jiàn)后文)的細(xì)微區(qū)別的:
第一,擴(kuò)展速度使用了貝塞爾曲線(xiàn),不是勻速,并且速度曲線(xiàn)的選擇有多種,第二種方法卻很難做到勻速意外的其他變速類(lèi)型;
第二,擴(kuò)展實(shí)際是往4個(gè)方向進(jìn)行的,如果將模仿的邊框?qū)挾仍O(shè)置的更大,這個(gè)效果更明顯,這主要是因?yàn)樵谏厦娲a中設(shè)置的scale3d(x,y,z)的3個(gè)值當(dāng)中,x和y都是改變的。
(2)方法二:使用2個(gè)偽元素來(lái)模仿左右、上下兩對(duì)邊框的擴(kuò)展。以左右邊框?yàn)槔杭僭O(shè)使用::before偽元素來(lái)實(shí)現(xiàn),此時(shí)將偽元素width設(shè)置為100%,height設(shè)置為0,top設(shè)置為50%,并將其左右邊框設(shè)定為需要寬度,上下邊框設(shè)置為0;在鼠標(biāo)懸浮時(shí),改變height為100%,top為0即可。
效果請(qǐng)見(jiàn)文末demo鏈接,代碼如下:
#top-bottom2::before,
#top-bottom2::after{
content:'';
position:absolute;
box-sizing:border-box;
}
#top-bottom2::before{
width:100%;
height:0;
top:50%;
border-left:2px solid #fff;
border-right:2px solid #fff;
-webkit-transition:height 0.3s linear,top 0.3s linear;
transition:height 0.3s linear,top 0.3s linear;
}
article figure:hover #top-bottom2::before{
height:100%;
top:0;
}
#top-bottom2::after{
width:0;
height:100%;
top:0;
left:50%;
border-top:2px solid #fff;
border-bottom:2px solid #fff;
-webkit-transition:width 0.3s linear,left 0.3s linear;
transition:width 0.3s linear,left 0.3s linear;
}
article figure:hover #top-bottom2::after{
width:100%;
left:0;
}
以上,需要特別注意box-sizing屬性的設(shè)定,如果按照w3c的標(biāo)準(zhǔn)Box Model,即content-box,此時(shí)兩個(gè)偽元素內(nèi)容區(qū)的寬高相同,但一個(gè)偽元素有左右邊框,一個(gè)偽元素有上下邊框,會(huì)使得最后形成的邊框存在縫隙,如下:

因此,在方法二中,對(duì)于偽元素,必須設(shè)定box-sizing為border-box。
?。?)邊框的其他效果一:
主要利用transition-delay屬性,在指定的時(shí)間開(kāi)始過(guò)渡效果,從而達(dá)到邊框的連續(xù)動(dòng)畫(huà)效果。效果請(qǐng)見(jiàn)文末demo鏈接,具體代碼請(qǐng)見(jiàn)文末代碼鏈接(過(guò)長(zhǎng)):
(4)邊框的其他效果二:
同時(shí)使用transform的scale3d()、rotate(),配合transform-origin屬性,達(dá)到效果:從按鈕四個(gè)角所在點(diǎn)出發(fā),垂直于邊框方向射出射線(xiàn),同時(shí)射線(xiàn)順時(shí)針旋轉(zhuǎn)回到邊框所在位置并最終耦合成邊框。效果圖如下,效果請(qǐng)見(jiàn)文末demo鏈接,具體代碼請(qǐng)見(jiàn)文末代碼鏈接:

以上,為整個(gè)任務(wù)的完成過(guò)程,及完成各個(gè)小任務(wù)的原理及使用屬性。此外,在完成demo期間,也注意到以下方面:
1.對(duì)transition的使用:平滑過(guò)渡是雙面的,在鼠標(biāo)未懸浮到懸浮時(shí)需做到平滑,在懸浮到未懸浮時(shí)也要做到平滑。對(duì)此,如果兩個(gè)過(guò)程的動(dòng)作相同(注意開(kāi)始時(shí)間也要相同),即兩次過(guò)渡的transition屬性設(shè)定相同,在原本的元素使用transition即可,偽類(lèi)選擇時(shí)的元素中不用再次設(shè)定,否則兩邊都要設(shè)定;
2.善用偽元素,偽元素只在渲染層表現(xiàn),不影響html的本來(lái)結(jié)構(gòu),通過(guò)使用偽元素,可以制作很多炫麗的效果;
3.對(duì)代碼進(jìn)行優(yōu)化,在完成demo之后,對(duì)css代碼進(jìn)行了優(yōu)化,存在選擇器不精煉、不同元素的相同樣式未合并、注釋不成體系等缺點(diǎn)。
最后,附上解決各個(gè)任務(wù)的參考資料:
1.“文字的上浮淡出”:這個(gè)小怪獸是在打完另外幾個(gè)小怪獸之后解決的,沒(méi)找?guī)褪志徒鉀Q了;
2.“文字顏色流光漸變效果”:主要參考了w3cplus大漠老師的《css3 background-clip》:http://www.w3cplus.com/content/css3-background-clip;
以及已完成這個(gè)任務(wù)的同學(xué)的筆記。w3cplus大漠老師的文章對(duì)學(xué)習(xí)css3非常有幫助,對(duì)transition、transform的使用,也參考了大漠老師的文章;
3.“背景模糊效果”:《css揭秘》第4章第18節(jié)毛玻璃效果;
4.“邊框擴(kuò)展”:在任務(wù)的網(wǎng)頁(yè)下方有在線(xiàn)參考資料,其中有Codrops的鏈接,Codrops網(wǎng)站的第二項(xiàng)“Inspiration for Line Menu Styles”就是各種按鈕效果的展示,其中就有邊框擴(kuò)展。作為github上的開(kāi)源項(xiàng)目,可直接fork下載項(xiàng)目源碼,進(jìn)行研究學(xué)習(xí)。邊框擴(kuò)展是其中一個(gè)叫ariel的高手做的。需要注意的是,這個(gè)項(xiàng)目中各類(lèi)按鈕的狀態(tài)變化是鼠標(biāo)懸浮、鼠標(biāo)點(diǎn)擊按鈕和鼠標(biāo)點(diǎn)擊其他按鈕三種,其中點(diǎn)擊事件使用了js代碼,效果的展現(xiàn)全是使用的css3屬性。(https://tympanus.net/codrops/category/playground/page/2/)

我的demo:http://smallstarz.com/baidutask-2017/nuomi-task1-mouseSuspending/mouseSuspending.html;
demo代碼:https://github.com/smallstar92/baidutask-2017/tree/gh-pages/nuomi-task1-mouseSuspending;