使用 button 的 5 個理由

XboxYan發表於2021-12-06

button 是平時使用最廣泛的一個 HTML 元素了,只要有點選互動的地方都推薦使用這個。但是,仍然有大部分網站使用的還是div,比如某博,所到之處幾乎都是 div

image-20211205163400613

既然是按鈕,為什麼不直接使用button呢?這裡介紹一下使用 button 的 5 個理由

一、禁用特性

button支援禁用。這也是表單元素的通性,直接設定disabled屬性可以達到禁用的效果

<button disabled>按鈕</button>

而且,這種禁用不僅可以禁用滑鼠點選,也會禁用鍵盤訪問,是真正意義上的禁用

image-20211205165035776

如果需要改變禁用用的樣式,需要通過:disabled偽類,而不是disabled屬性

button:disabled{
  
}
/*不推薦*/
button[disabled]{
  
}

因為有時候 button 被禁用,不一定來源於自身,有可能是因為父級元素,比如fieldset

<fieldset disabled>
    <button>按鈕</button>
    <button>按鈕</button>
</fieldset>

image-20211205165452039

可以看到,當fieldset被禁用時,所包含的表單元素全部都被禁用,這些表單元素本身是沒有disabled屬性的,所以要禁用一個按鈕,一定要通過:disabled偽類

另外在 div 中,一般通過 pointer-events: none;來實現,不過這種只能禁用掉滑鼠行為

div.disabled{
  pointer-events: none;
}

當然對於 div來說,這個方式已經足夠,因為 div 本身也不會被聚焦到

二、盒子模型和居中特性

button的預設盒子屬性是 border-box,進一步擴充套件開來,幾乎所有表單元素的盒子屬性都是 border-box

所以,在給按鈕設定具體尺寸的時候就不需要再設定這個了

button{
  padding: 5px 10px;
  width: 100%;
  box-sizing: border-box; /* 不需要 */
}

image-20211205150145229

然後,button中預設是垂直水平居中的。

介於幾乎所有的按鈕都是居中的設計,所以,你無需設定任何居中屬性就能達到水平垂直居中的效果

button{
  width: 100px;
  height: 100px;
  text-align: center;  /* 不需要 */
  line-height: 50px;  /* 不需要 */
}

image-20211205150248450

三、鍵盤訪問

button支援鍵盤訪問。當使用 tab鍵進行焦點切換時,會有明顯的焦點提示(outline)。而且在聚焦狀態,通過鍵盤 enter 或者 space鍵可以觸發按鈕的點選事件

(下面是鍵盤操作,使用 tab 聚焦,然後通過 enter 或者 space鍵觸發點選)

Kapture 2021-12-05 at 15.04.16

所以,為了保持鍵盤訪問的可見性,最好不要這麼做

button{
  outline: 0; /* 最好不要這麼做 */
}

預設情況下,這個 outline只會在鍵盤聚焦時出現,而滑鼠點選聚焦不會出現,如果需要改變聚焦的顏色,可以僅僅改變 outline-color,這樣不會影響瀏覽器預設的出現時機

button{
  outline-color: salmon;
}

Kapture 2021-12-05 at 15.24.23

最好不要改變整個outline,這樣會導致不管是鍵盤聚焦還是滑鼠點選聚焦都會出現 outline(一般設計都不喜歡滑鼠點選有outline

/* 最好不要這麼做 */
button:focus{
  outline: 1px solid salmon;
}

如果想完全控制鍵盤聚焦的樣式,可以使用這個偽類:focus-visible,相容性略差

button:focus-visible{
  outline: 5px solid salmon;
}

Kapture 2021-12-05 at 15.28.51

四、表單特性

button具備一些表單特性。合理使用這些特性,不需要 js 也能實現很多互動,比如這樣一個表單

<form>
    <label>使用者: </label><input name="user" required><br>
    <label>密碼: </label><input name="password" type="password" required><br>
    <button type="submit">登入</button>
    <button type="reset">重置</button>
</form>

其中,type="submit"天然支援表單提交,也就是觸發 formsubmit 事件,而且也支援回車登入,這樣體驗就非常好了,輸完使用者名稱密碼,可以直接敲擊回車登入。

type="reset"可以執行表單的重置,注意這裡是重置,而不是清空,可能理解成還原會更好。然後這個特性之前已經這篇文章中得到了應用:CSS 實現搜尋相關互動

Kapture 2021-12-05 at 15.46.25

如果不使用 button,你可能需要更多的javascript來實現類似的功能,而且還有可能出現不為人知的 bug

五、螢幕閱讀

button預設支援螢幕閱讀訪問。比如使用macOS自帶的旁白,在讀到一個按鈕時,可以很清楚的明白這是一個按鈕還有內部的文字

image-20211205155407462

如果是一個 div,如果想達到這樣的效果,可能需要

  1. 為了使 div聚焦,需要新增 tabindex=0屬性
  2. 為了使div被識別成按鈕,需要新增role="button"屬性

有時候還有更極端的情況,直接使用背景圖作為按鈕,沒有文字,還需要以下操作

  1. 為了使div能夠被識別內容,需要新增 aria-label屬性
<div tabindex="0" role="button" aria-label="登入2">登入</div>

這樣螢幕閱讀基本就能正常訪問了

image-20211205160830791

沒錯,文章開頭的做法就是這樣的,再來回顧一下這些茫茫多的屬性

image-20211205163408302

既然要這麼麻煩,為何不直接用 button呢?

六、為何不使用button

以下是我個人的一些猜想

  1. button 在各個瀏覽器的樣式表現不一致
  2. button 不能包含某些標籤或者會導致無效,比如a標籤
  3. 歷史原因,以前就用 div實現了,不想折騰
  4. 不知道button有這麼多好用的特性
  5. 不在乎這些,能實現就行,我的 js 非常強
  6. 實際專案中不需要鍵盤訪問或者螢幕閱讀
  7. 某些第三方元件庫的封裝

七、總結和說明

以上從樣式和功能上介紹了原生 button元素的幾個特性,同時還猜想了一些沒有使用button的原因,下面總結一下:

  1. button支援禁用特性,通過:disabled偽類自定義禁用樣式
  2. button預設盒子模型是border-box
  3. button內預設水平垂直居中
  4. button支援鍵盤訪問,在聚焦狀態下可以通過enter或者space觸發點選事件
  5. button鍵盤聚焦的outline可以通過outline-color修改顏色,也可以通過:focus-visible自定義鍵盤聚焦樣式
  6. button在表單中支援enter提交表單
  7. button在表單中有重置功能
  8. button預設支援螢幕閱讀

雖然有這麼多好用的特性,但是實際開發中還是有很多原因沒有使用。不過不管以前如何如何,從現在開始,只要碰到"按鈕",第一優先選擇button就可以了,不用做過多修飾,就能在不知不覺中提升使用者體驗。最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤

相關文章