<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          CSS 實現(xiàn)按鈕點擊動效的套路

          共 4474字,需瀏覽 9分鐘

           ·

          2022-04-18 10:29

          大廠技術(shù)??高級前端??Node進階

          點擊上方?程序員成長指北,關(guān)注公眾號

          回復(fù)1,加入高級Node交流群


          在 Web 中,大部分按鈕可能都是平平無奇的,有時候為了強調(diào)品牌特殊或者滿足特殊功能,可能需要給按鈕添加一點點擊動效。比如,用過 Ant Design 的小伙伴應(yīng)該都能發(fā)現(xiàn),在點擊按鈕的時候會有一個很微妙的水波動畫

          Kapture 2022-02-10 at 18.55.48

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

          動畫過程其實不復(fù)雜,看了一下官方的實現(xiàn),是通過 js 動態(tài)更改屬性實現(xiàn)的,在點擊的時候,改變屬性,觸發(fā)動畫,當(dāng)動畫結(jié)束之后,再將該屬性還原(還原是為了保證下次點擊仍然有動畫),如下

          image-20220211184419600

          看著好像有點麻煩?其實,這種效果也是可以純 CSS 實現(xiàn)的,而且還能實現(xiàn)其他更多有趣的效果

          Kapture 2022-02-11 at 20.02.15

          一起看看吧~

          一、CSS 過渡動畫

          通常 CSS 中實現(xiàn)動畫有兩種思路,transitionanimation。一般而言,簡單的、需要主動觸發(fā)(:hover 、:active或者動態(tài)切換類名等)的可以用transition實現(xiàn),其他的都可以用animation。

          回到這個例子,動畫足夠簡單了,就兩個變化,而且需要主動觸發(fā)(這里是點擊,可以想到:active),所以優(yōu)先考慮用transition來實現(xiàn)。

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

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

          那么,這個動畫(過渡)的兩種狀態(tài)可以這樣來表示

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

          嗯,兩種狀態(tài)的樣式都寫好了,怎么觸發(fā)點擊呢?

          二、CSS 點擊動畫

          先完善一下基本樣式,假設(shè) HTML 結(jié)構(gòu)如下

          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來觸發(fā)過渡動畫,可能會這樣來實現(xiàn)

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

          效果如下:

          Kapture 2022-02-10 at 20.35.12

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

          三、CSS 過渡重置

          為什么會有上面這種現(xiàn)象呢?這里提一下:active:active只有在鼠標(biāo)按下時才會起作用,通常在點擊一個按鈕時,都是輕輕地點擊,而不是長按,如果在:active上添加動畫,那么在鼠標(biāo)抬起的時候,動畫一般都沒有結(jié)束,所以會導(dǎo)致在鼠標(biāo)抬起的時候,動畫馬上就停止了,如果是transition,還會有一個“回退”的過渡效果。

          那么,有沒有什么方法可以只在鼠標(biāo)抬起的時候產(chǎn)生動畫呢?

          我的實現(xiàn)是這樣的,假設(shè)默認就是有陰影(透明度為0)的狀態(tài),在:active的時候迅速去除陰影(這里的“迅速”,是指取消按下去的過渡動畫),然后由于默認是有過渡的,所以鼠標(biāo)抬起的時候陰影就回退到有陰影的狀態(tài)了,這樣可以保證按下去是沒有動畫的,抬起來觸發(fā)過渡動畫

          整個流程其實是這樣:

          image-20220214104311207

          取消過渡動畫也很簡單,設(shè)置時長為 0 就行了,代碼實現(xiàn)就是這樣

          .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;?/*取消過渡*/
          }

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

          Kapture 2022-02-10 at 20.56.07

          這樣就實現(xiàn)了和 Ant Design 幾乎相同的點擊效果

          四、其他動效案例

          上面其實提供了一種思路,只要是這種點擊動畫,都可以采用這種方式來實現(xiàn)。比如這樣一個刷新按鈕,需要點擊的時候轉(zhuǎn)一下

          Kapture 2022-02-10 at 21.14.32

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

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

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

          Kapture 2022-02-10 at 21.18.41

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

          Kapture 2022-02-11 at 14.08.54

          在之前文章CSS實現(xiàn)一個粒子動效的按鈕中已經(jīng)有講到,這里就不多說了,完整代碼可以訪問 button-active (codepen.io)

          五、更復(fù)雜的動畫

          前面提到過,簡單的動畫可以用過渡transition來實現(xiàn),那么稍微復(fù)雜點的,比如下面這種 “Q彈Q彈” 的按鈕

          Kapture 2022-02-11 at 14.13.25

          這類動畫,單純的transition就無能為力了,必須借助animation來實現(xiàn),原理還是類似

          先定義一個動畫關(guān)鍵幀

          @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;
          }

          這樣就實現(xiàn)了,是不是出乎意料的容易?

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

          Kapture 2022-02-11 at 14.20.28

          那么,如何避免首次進來時動畫不執(zhí)行呢?

          這里有一個小技巧,可以在默認情況下設(shè)置動畫時長為 0 ,這樣在首次動畫執(zhí)行后,馬上就結(jié)束了,然后在 hover時恢復(fù)默認的動畫時長,由于動畫已經(jīng)結(jié)束,改變動畫時長也不會觸發(fā)動畫再次運行,所以實現(xiàn)就是

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

          這樣刷新頁面就不會再有動畫了

          Kapture 2022-02-11 at 14.28.44

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

          Kapture 2022-02-11 at 19.59.00

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

          Kapture 2022-02-11 at 20.02.15

          六、總結(jié)和說明

          以上就是關(guān)于 CSS 點擊動畫的幾個套路和一些案例,其實就是默認執(zhí)行動畫,點擊時重置一下就行了。整體來說代碼很簡單,只是理解起來可能不是特別順暢,下面總結(jié)一下實現(xiàn)要點:

          1. 簡單動畫用transition,其他用 animation
          2. transition 可以通過設(shè)置時長為 0 來重置
          3. animation 可以通過設(shè)置 none 來重置
          4. 在 :active 時重置動畫,點擊后會再次運行動畫
          5. 復(fù)雜的動畫可以借助現(xiàn)有的動畫庫,例如 anmate.css
          6. 設(shè)置動畫時長為 0 可以避免首次渲染出現(xiàn)動畫

          相比 js 實現(xiàn),CSS 實現(xiàn)代碼更少,加載更快,無需等待 js 加載完成,體驗更優(yōu)(比如天然支持敲空格鍵觸發(fā)),同時也更容易維護和使用,直接復(fù)制一個類名就行了。最后,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉(zhuǎn)發(fā)???

          關(guān)于本文

          作者:XboxYan

          https://segmentfault.com/a/1190000041400360

          Node 社群



          我組建了一個氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學(xué)習(xí)感興趣的話(后續(xù)有計劃也可以),我們可以一起進行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。



          如果你覺得這篇內(nèi)容對你有幫助,我想請你幫我2個小忙:

          1. 點個「在看」,讓更多人也能看到這篇文章
          2. 訂閱官方博客?www.inode.club?讓我們一起成長

          點贊和在看就是最大的支持??

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产成人精品白浆久久69 | www.色播| 综合久久久福利蜜芽 | 毛片网X4W一7CC | 成人黄色在线免费 |