CSS實現(xiàn)一個讓面試官眼前一亮的故障風(fēng)格文字動畫

該動畫效果就比較復(fù)雜了,用到的知識比較多,例如 「css偽元素 、元素自定義屬性 、蒙版屬性 、animation動畫等等」
標(biāo)簽元素部分
<body>
<div class="txt" data-text="我是故障風(fēng)格的文字">
我是故障風(fēng)格的文字
</div>
</body>
這里我們使用了自定義屬性,即 「data-」 加上我們自定義的屬性名,我們將我們的文字內(nèi)容作為該屬性的值,方便之后偽元素獲取到對應(yīng)的文字
「@keyframes部分」
@keyframes animation-before{
0% {
clip-path: inset(0 0 0 0);
}
5% {
clip-path: inset(.8em 0 .4em 0);
}
10% {
clip-path: inset(.4em 0 .8em 0);
}
15% {
clip-path: inset(.1em 0 1em 0);
}
20% {
clip-path: inset(.3em 0 .6em 0);
}
25% {
clip-path: inset(.6em 0 .3em 0);
}
30% {
clip-path: inset(.8em 0 .5em 0);
}
35% {
clip-path: inset(1em 0 .1em 0);
}
40% {
clip-path: inset(.7em 0 .35em 0);
}
45% {
clip-path: inset(.5em 0 .2em 0);
}
50% {
clip-path: inset(.2em 0 .5em 0);
}
55% {
clip-path: inset(.35em 0 .7em 0);
}
60% {
clip-path: inset(.1em 0 .9em 0);
}
65% {
clip-path: inset(.8em 0 .46em 0);
}
70% {
clip-path: inset(.66em 0 .33em 0);
}
75% {
clip-path: inset(.48em 0 .23em 0);
}
80% {
clip-path: inset(.23em 0 .48em 0);
}
85% {
clip-path: inset(.39em 0 .79em 0);
}
90% {
clip-path: inset(.33em 0 .66em 0);
}
95% {
clip-path: inset(1em 0 .3em 0);
}
100% {
clip-path: inset(.62em 0 .29em 0);
}
}
@keyframes animation-after{
0% {
clip-path: inset(0 0 0 0);
}
5% {
clip-path: inset(.4em 0 .8em 0);
}
10% {
clip-path: inset(.8em 0 .4em 0);
}
15% {
clip-path: inset(1em 0 .1em 0);
}
20% {
clip-path: inset(.6em 0 .3em 0);
}
25% {
clip-path: inset(.3em 0 .6em 0);
}
30% {
clip-path: inset(.5em 0 .8em 0);
}
35% {
clip-path: inset(.1em 0 1em 0);
}
40% {
clip-path: inset(.35em 0 .7em 0);
}
45% {
clip-path: inset(.2em 0 .5em 0);
}
50% {
clip-path: inset(.5em 0 .2em 0);
}
55% {
clip-path: inset(.7em 0 .35em 0);
}
60% {
clip-path: inset(.9em 0 .1em 0);
}
65% {
clip-path: inset(.46em 0 .8em 0);
}
70% {
clip-path: inset(.3em 0 .66em 0);
}
75% {
clip-path: inset(.23em 0 .48em 0);
}
80% {
clip-path: inset(.48em 0 .23em 0);
}
85% {
clip-path: inset(.79em 0 .39em 0);
}
90% {
clip-path: inset(.66em 0 .33em 0);
}
95% {
clip-path: inset(.3em 0 1em 0);
}
100% {
clip-path: inset(.29em 0 .62em 0);
}
}
這里我們設(shè)置了兩個keyframes,分別為 「animation-before」 、「animation-after」
想必已經(jīng)很明顯了,前者是準(zhǔn)備給我們后面的偽元素 before 使用的 ;后者是給我們后面的偽元素 after 使用的
那么其中用到的 clip-path 是干什么用的呢?這個是css3的一個新屬性,叫做「蒙版」,而其中的 inset() 值表示的是蒙版形狀為矩形
我們來看一下它的用法
首先 inset() 接收四個長度參數(shù),分別表示蒙版距離元素標(biāo)簽的「上側(cè)」 、「右側(cè)」 、「下側(cè)」 、「左側(cè)」的距離,從而決定了蒙版的大小
當(dāng)我們設(shè)置為 inset(0 0 0 0)時,表示蒙版作用區(qū)域大小跟元素標(biāo)簽一樣大,如下圖所示(紅色邊框表示蒙版的作用區(qū)域)

此時我們的文字是可以完全展示出來的,因為蒙版的作用區(qū)域就是我們標(biāo)簽元素的大小
然后我們再來看一下,如果我們的設(shè)置為 inset(30px 0 0 0) ,則測試表示,蒙版的作用區(qū)域距離標(biāo)簽元素的上側(cè) 30px,距離其它的邊 0px,如圖所示

圖中藍(lán)色邊框的部分不是蒙版的作用區(qū)域,因此我們無法看到該區(qū)域的內(nèi)容,真實情況如下圖所示

在了解了蒙版的使用情況了以后,我們就通過 @keyframes 來設(shè)置逐幀動畫,使蒙版的作用區(qū)域在垂直方向一直變化,實現(xiàn)上下抖動的效果,代碼就如上所述
具體樣式
body{
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: black;
}
.txt{
display: inline-block;
font-size: 65px;
font-weight: 600;
padding: 0 4px;
color: white;
position: relative;
}
.txt::before{
/* 獲取文本 */
content: attr(data-text);
position: absolute;
/* 向左側(cè)移2px */
left: -2px;
width: 100%;
/* 將背景色設(shè)為與主背景同樣的顏色,用于遮擋我們的標(biāo)簽元素 */
background: black;
/* 給before偽元素的文本添加左側(cè)2px大小的紅色文字陰影 */
text-shadow:2px 0 red;
/* 應(yīng)用蒙版垂直變化動畫,并一直循環(huán) */
animation: animation-before 3s infinite linear alternate-reverse;
}
.txt::after{
/* 獲取文本 */
content: attr(data-text);
position: absolute;
/* 向左側(cè)移2px */
left: 2px;
width: 100%;
/* 將背景色設(shè)為與主背景同樣的顏色,用于遮擋我們的標(biāo)簽元素 */
background: black;
/* 給before偽元素的文本添加右側(cè)2px大小的藍(lán)色文字陰影 */
text-shadow: -2px 0 blue;
/* 應(yīng)用蒙版垂直變化動畫,并一直循環(huán) */
animation: animation-after 3s infinite linear alternate-reverse;
}
這里,我們設(shè)置了兩個偽元素 before 和 after,分別定位到跟父元素同樣的位置,然后分別向左、右側(cè)移一點點的距離,制作一個錯位的效果,然后都將背景色設(shè)置為與父元素背景色一樣的顏色,用于遮擋父元素。
然后設(shè)置了蒙版垂直變化動畫以后,被蒙版遮擋的部分雖然看不到了,但是會露出下面一層的父元素內(nèi)容,這樣就可以實現(xiàn)了一個完美的故障風(fēng)格的文字展示動畫了。
