3分鐘 2023-09-08

網頁設計特效-互動按鈕

製作特效可以給予使用者明確的回饋,告訴使用者目前按鈕或某個東西的狀態是什麼,讓使用者可以採取對應的動作。這一次我們挑選了「按鈕」這個元件作為範例,看看我們是如何使用 CSS + Javascript + SVG 思考並實踐特效的!

CSS| 虛擬類別、Class、transition

CSS 的虛擬類別(又稱偽類別)通常是對應元素的特殊情況,例如滑鼠移入(hover)、被選取(checked)、聚焦(focus)等狀態,而在按鈕的部分我們比較常使用 hover 這個虛擬類別。

另一個在 CSS 常用的手法則是為不同的狀態建立不同的 Class,透過操作 DOM 元素來達成切換 Class。這一個手法主要是針對沒辦法透過上面虛擬類別達成的特效,像某個按鈕要在選單打開時呈現不同狀態。

transition 則是很常用的屬性,才能讓 Class 在切換時呈現動畫的效果,否則會死板板的一點動感都沒有喔!

 

▲ 使用與不使用 transition 的效果
 

Javascript|事件、操作 DOM

Javascript 通常被我們用來設定事件並操作 DOM 來切換 Class,像是按下某個按鈕就會打開選單,並改變按鈕的狀態,此時就可以在按鈕上寫一個 onclick 事件來做這件事情。關於 Javascript 的滑鼠事件可以參考這裡!如果有用 jQuery 之類的話,可能就要看官方的文件囉!

SVG|繪製圖形

SVG 是一個向量圖檔格式,在 Html 當中可以直接繪製 SVG,像是這個網站提供了很多 SVG 素材可以使用,除了提供下載之外,也可以直接 COPY 現成的 Html 程式碼來使用喔!

這一部分我們沒有著墨太多,除了這次的按鈕只有三條線之外XD,所以想了解更多繪製 SVG 的細節,可以參考MDN上面的文件,裡面介紹了更多不同繪製 SVG 的路徑與形狀,像是這次的三條線就只有用到「line」這個路徑形狀。

<svg id="MenuIcon" width="69px" height="69px" viewBox="0 0 69 69" xmlns="http://www.w3.org/2000/svg">
      <line id="mil1" x1="15" y1="41" x2="69" y2="41"></line>
      <line id="mil2" x1="15" y1="53" x2="69" y2="53"></line>
      <line id="mil3" x1="15" y1="65" x2="69" y2="65"></line>
</svg>

▲ 本次使用的 SVG ,簡單的三條線XD

動畫狀態的設計

上面已經說完實踐的技術方法,再來要說說思考動畫的各種狀態,以我們這次舉例的按鈕來說通常有幾種狀態:原始、滑鼠移入、滑鼠移出(回歸原始)、點擊,而在「點擊」的部分又被我們分成關閉時點擊開啟時點擊兩種狀態。一些常見的狀態如 hover(滑鼠移入)、focus(聚焦)等狀態通常直接使用 CSS 虛擬類別達成就可以了,但如果因應不同的特殊狀態就可能需要建立不同的 Class 並使用 Javascript 進行切換了!

另外這些狀態會因應特效及對應的功能而不同,像是這一次點擊的部分,因為會分成選單開啟時以及選單關閉時兩種狀態,按鈕要呈現不同狀態以及做不同的動作:選單打開時要要做關閉選單及關閉的動畫、選單關閉的時候要做打開選單及打開的動畫。

 

▲ 依據選單的狀態,右上方的選單按鈕呈現不同狀態(studio-44s 官方)

 

決定好不同的狀態之後,就可以寫成 CSS 了!

/* MENU 按鈕被點開的時候,讓 svg 呈現叉叉狀態 */
.is-navbar-on #MenuIcon #mil1 {
  transition: all 0.3s;
  transform: translate3d(38px, -20px, 0px) rotate(45deg);
  stroke: #E86A33;
}

.is-navbar-on #MenuIcon #mil2 {
  transition: all 0.3s;
  transform: translateX(-100px);
}

.is-navbar-on #MenuIcon #mil3 {
  transition: all 0.3s;
  transform: translate3d(-38px, 20px, 0px) rotate(-45deg);
  stroke: #E86A33;
}

/* MENU 關閉時復原按鈕 (恢復三條線)*/
.is-navbar-close #MenuIcon #mil1 {
  transition: all 0.3s;
  transform: translate3d(0px, 0px, 0px) rotate(0deg);
}

.is-navbar-close #MenuIcon #mil2 {
  transition: all 0.3s;
  transform: translateX(0px);
}

.is-navbar-close #MenuIcon #mil3 {
  transition: all 0.3s;
  transform: translate3d(0px, 0px, 0px) rotate(0deg);
}

/* MENU 關閉時,滑鼠放到按鈕上的效果(改變第一條跟第二條線的位置) */
.is-navbar-close #MenuIcon:hover #mil1 {
  transition: all 0.3s;
  transform: rotate(5deg);
  stroke: #E86A33;
}

.is-navbar-close #MenuIcon:hover #mil2 {
  transition: all 0.3s;
  transform: translateX(-10px);
  stroke: #E86A33;
}

.is-navbar-close #MenuIcon:hover #mil3 {
  transition: all 0.3s;
  stroke: #E86A33;
}

/* 按鈕最基本的狀態(選單關閉時) */
#MenuIcon #mil1 {
  transition: all 0.3s;
  transform: rotate(0deg);
  stroke: #263A29;
  stroke-width: 3;
}

#MenuIcon #mil2 {
  transition: all 0.3s;
  transform: translateX(0px);
  stroke: #263A29;
  stroke-width: 3;
}

#MenuIcon #mil3 {
  transition: all 0.3s;
  stroke: #263A29;
  stroke-width: 3;
}

▲ 依據選單狀態而有不同的 CSS Class

Javascript 的部分會需要處理點擊後選單打開後的狀態,因此要來改變按鈕的 Class。這一段程式碼用 jQuery 完成,用原始的 Javascript 也可以做到。

$('.menuBtn').click(function(){
  $('.menuBtn').toggleClass('is-navbar-on');
  $('.menuBtn').toggleClass('is-navbar-close');
});

▲ 利用修改 Class 來改變按鈕狀態

總結

以上就是本次設計按鈕的整個過程啦!想看全部的程式碼可以去這個CodePen

設計動畫的初衷還是給予使用者適當的回饋,得到使用者的關注,並讓使用者可以做出對應的動作,並順帶塞入一些炫砲或者可愛的效果啦xD,但是在能力、成本與時間的多方考量上每增加一個看似單純的動畫都要耗費不少工時,所以能做到什麼程度,就很難說啦。

最後推薦一個網站,上面有很多五花八門的按鈕特效,可以看看喔!

挑戰跨足工程師與設計師的反骨少年:D