天天看點

「前端」解密 CSS 實作按鈕點選動效的套路

在 Web 中,大部分按鈕可能都是平平無奇的,有時候為了強調品牌特殊或者滿足特殊功能,可能需要給按鈕添加一點點選動效。比如,用過 Ant Design 的小夥伴應該都能發現,在點選按鈕的時候會有一個很微妙的水波動畫

「前端」解密 CSS 實作按鈕點選動效的套路

這就非常有特色了,看到這樣的按鈕自然會聯系上 Ant Design 。

動畫過程其實不複雜,看了一下官方的實作,是通過 js 動态更改屬性實作的,在點選的時候,改變屬性,觸發動畫,當動畫結束之後,再将該屬性還原(還原是為了保證下次點選仍然有動畫),如下

「前端」解密 CSS 實作按鈕點選動效的套路

看着好像有點麻煩?其實,這種效果也是可以純 CSS 實作的,而且還能實作其他更多有趣的效果

「前端」解密 CSS 實作按鈕點選動效的套路

一起看看吧~

一、CSS 過渡動畫

通常 CSS 中實作動畫有兩種思路,transition和animation。一般而言,簡單的、需要主動觸發(:hover 、:active或者動态切換類名等)的可以用transition實作,其他的都可以用animation。

回到這個例子,動畫足夠簡單了,就兩個變化,而且需要主動觸發(這裡是點選,可以想到:active),是以優先考慮用transition來實作。

觀察整個動畫,其實就是兩個效果疊加而成

  1. 陰影不斷擴大
  2. 透明度不斷降低

那麼,這個動畫(過渡)的兩種狀态可以這樣來表示

/* 初始狀态 */
button{
  opacity: .4;
  transition: .3s;
}
/* 擴散狀态 */
button{
  box-shadow: 0 0 0 6px var(--primary-color);
  opacity: 0;
}           

嗯,兩種狀态的樣式都寫好了,怎麼觸發點選呢?

二、CSS 點選動畫

先完善一下基本樣式,假設 HTML 結構如下

<button class="button">Default</button>           

簡單美化一下

:root{
  --primary-color: royalblue;
}
.button{
  padding: 5px 16px;
  color: #000000d9;
  border: 1px solid #d9d9d9;
  background-color: transparent;
  border-radius: 2px;
  line-height: 1.4;
  box-shadow: 0 2px #00000004;
  cursor: pointer;
  transition: .3s;
}
.button:hover{
  color: var(--primary-color);
  border-color: currentColor;
}           

然後添加陰影擴散動畫,為了友善透明度的控制,這裡用::after僞類單獨渲染

.button::after{
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0.4;
  transition: .3s;
}           

如果按照正常的思路通過:active來觸發過渡動畫,可能會這樣來實作

.button:active::after{
  box-shadow: 0 0 0 6px var(--primary-color);
  opacity: 0;
}           

效果如下:

「前端」解密 CSS 實作按鈕點選動效的套路

嗯,好像不大對勁?接着往下看

三、CSS 過渡重置

為什麼會有上面這種現象呢?這裡提一下:active。:active隻有在滑鼠按下時才會起作用,通常在點選一個按鈕時,都是輕輕地點選,而不是長按,如果在:active上添加動畫,那麼在滑鼠擡起的時候,動畫一般都沒有結束,是以會導緻在滑鼠擡起的時候,動畫馬上就停止了,如果是transition,還會有一個“回退”的過渡效果。

那麼,有沒有什麼方法可以隻在滑鼠擡起的時候産生動畫呢?

我的實作是這樣的,假設預設就是有陰影(透明度為0)的狀态,在:active的時候迅速去除陰影(這裡的“迅速”,是指取消按下去的過渡動畫),然後由于預設是有過渡的,是以滑鼠擡起的時候陰影就回退到有陰影的狀态了,這樣可以保證按下去是沒有動畫的,擡起來觸發過渡動畫

整個流程其實是這樣:

「前端」解密 CSS 實作按鈕點選動效的套路

取消過渡動畫也很簡單,設定時長為 0 就行了,代碼實作就是這樣

.button::after{
  /*其他樣式*/
  opacity: 0;
  box-shadow: 0 0 0 6px var(--primary-color);
  transition: .3s;
}
/*點選*/
.button:active::after{
  box-shadow: none;
  opacity: 0.4;
  transition: 0s; /*取消過渡*/
}           

然後,神奇的效果就出來了!

「前端」解密 CSS 實作按鈕點選動效的套路

這樣就實作了和 Ant Design 幾乎相同的點選效果

四、其他動效案例

上面其實提供了一種思路,隻要是這種點選動畫,都可以采用這種方式來實作。比如這樣一個重新整理按鈕,需要點選的時候轉一下

「前端」解密 CSS 實作按鈕點選動效的套路

用這種思路就很容易了,這個例子比上面那個要簡單一些,畢竟隻有旋轉變化,沒有透明度變化,核心代碼如下

.icon{
    transform: rotate(360deg);
    transition: .5s;
}
.button:active .icon{
    transform: rotate(0);
    transition: 0s;
}
           

完整代碼可以通路 ant design button (codepen.io),整合了更多的 demo

「前端」解密 CSS 實作按鈕點選動效的套路

再比如這樣的點選粒子動效,原理也是相同的

「前端」解密 CSS 實作按鈕點選動效的套路

在之前文章CSS實作一個粒子動效的按鈕中已經有講到,這裡就不多說了,完整代碼可以通路 button-active (codepen.io)

五、更複雜的動畫

前面提到過,簡單的動畫可以用過渡transition來實作,那麼稍微複雜點的,比如下面這種 “Q彈Q彈” 的按鈕

「前端」解密 CSS 實作按鈕點選動效的套路

這類動畫,單純的transition就無能為力了,必須借助animation來實作,原理還是類似

先定義一個動畫關鍵幀

@keyframes tada {
    from {
        transform: scale3d(1, 1, 1)
    }
    10%, 20% {
        transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg)
    }
    30%, 50%, 70%, 90% {
        transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)
    }
    40%, 60%, 80% {
        transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)
    }
    to {
        transform: scale3d(1, 1, 1)
    }
}
           
這個動畫來自于 Animate.css 中的 tada,直接 copy 過來就行

然後讓按鈕動起來

.button{
  animation: tada 1s;
}           

在點選的時候重置動畫,直接重置動畫,animation可能會更好了解一些,這樣在擡起的時候會重新運作動畫

.button:active{
  animation: none;
}           

這樣就實作了,是不是出乎意料的容易?

不過有一點小瑕疵,每次頁面重新整理,按鈕會主動進行一次動畫(因為動畫是自動執行的),如下

「前端」解密 CSS 實作按鈕點選動效的套路

那麼,如何避免首次進來時動畫不執行呢?

這裡有一個小技巧,可以在預設情況下設定動畫時長為 0 ,這樣在首次動畫執行後,馬上就結束了,然後在 hover時恢複預設的動畫時長,由于動畫已經結束,改變動畫時長也不會觸發動畫再次運作,是以實作就是

.button{
  animation: jump 0s;
}
.button:hover{
  animation-duration: 1s;
}
.button:active{
  animation: none;
}           

這樣重新整理頁面就不會再有動畫了

「前端」解密 CSS 實作按鈕點選動效的套路

接下來,借助 animate.css 你可以更換任意的動畫,比如

「前端」解密 CSS 實作按鈕點選動效的套路

完整代碼可以通路button-jump (codepen.io),整合了更多的 demo

「前端」解密 CSS 實作按鈕點選動效的套路

六、總結和說明

以上就是關于 CSS 點選動畫的幾個套路和一些案例,其實就是預設執行動畫,點選時重置一下就行了。整體來說代碼很簡單,隻是了解起來可能不是特别順暢,下面總結一下實作要點:

  1. 簡單動畫用transition,其他用 animation
  2. transition 可以通過設定時長為 0 來重置
  3. animation 可以通過設定 none 來重置
  4. 在 :active 時重置動畫,點選後會再次運作動畫
  5. 複雜的動畫可以借助現有的動畫庫,例如 anmate.css
  6. 設定動畫時長為 0 可以避免首次渲染出現動畫

相比 js 實作,CSS 實作代碼更少,加載更快,無需等待 js 加載完成,體驗更優(比如天然支援敲空格鍵觸發),同時也更容易維護和使用,直接複制一個類名就行了。

文章來源:XboxYan_https://juejin.cn/post/7064404257436336135