button
是平時使用最廣泛的一個 HTML 元素了,只要有點選互動的地方都推薦使用這個。但是,仍然有大部分網站使用的還是div
,比如某博,所到之處幾乎都是 div
既然是按鈕,為什麼不直接使用button
呢?這裡介紹一下使用 button 的 5 個理由
一、禁用特性
button
支援禁用。這也是表單元素的通性,直接設定disabled
屬性可以達到禁用的效果
<button disabled>按鈕</button>
而且,這種禁用不僅可以禁用滑鼠點選,也會禁用鍵盤訪問,是真正意義上的禁用
如果需要改變禁用用的樣式,需要通過:disabled
偽類,而不是disabled
屬性
button:disabled{
}
/*不推薦*/
button[disabled]{
}
因為有時候 button
被禁用,不一定來源於自身,有可能是因為父級元素,比如fieldset
<fieldset disabled>
<button>按鈕</button>
<button>按鈕</button>
</fieldset>
可以看到,當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; /* 不需要 */
}
然後,button
中預設是垂直水平居中的。
介於幾乎所有的按鈕都是居中的設計,所以,你無需設定任何居中屬性就能達到水平垂直居中的效果
button{
width: 100px;
height: 100px;
text-align: center; /* 不需要 */
line-height: 50px; /* 不需要 */
}
三、鍵盤訪問
button
支援鍵盤訪問。當使用 tab
鍵進行焦點切換時,會有明顯的焦點提示(outline
)。而且在聚焦狀態,通過鍵盤 enter
或者 space
鍵可以觸發按鈕的點選事件
(下面是鍵盤操作,使用 tab
聚焦,然後通過 enter
或者 space
鍵觸發點選)
所以,為了保持鍵盤訪問的可見性,最好不要這麼做
button{
outline: 0; /* 最好不要這麼做 */
}
預設情況下,這個 outline
只會在鍵盤聚焦時出現,而滑鼠點選聚焦不會出現,如果需要改變聚焦的顏色,可以僅僅改變 outline-color
,這樣不會影響瀏覽器預設的出現時機
button{
outline-color: salmon;
}
最好不要改變整個outline
,這樣會導致不管是鍵盤聚焦還是滑鼠點選聚焦都會出現 outline
(一般設計都不喜歡滑鼠點選有outline
)
/* 最好不要這麼做 */
button:focus{
outline: 1px solid salmon;
}
如果想完全控制鍵盤聚焦的樣式,可以使用這個偽類:focus-visible
,相容性略差
button:focus-visible{
outline: 5px solid salmon;
}
四、表單特性
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"
天然支援表單提交,也就是觸發 form
的 submit
事件,而且也支援回車登入,這樣體驗就非常好了,輸完使用者名稱密碼,可以直接敲擊回車登入。
type="reset"
可以執行表單的重置,注意這裡是重置,而不是清空,可能理解成還原會更好。然後這個特性之前已經這篇文章中得到了應用:CSS 實現搜尋相關互動
如果不使用 button
,你可能需要更多的javascript
來實現類似的功能,而且還有可能出現不為人知的 bug
五、螢幕閱讀
button
預設支援螢幕閱讀訪問。比如使用macOS自帶的旁白,在讀到一個按鈕時,可以很清楚的明白這是一個按鈕還有內部的文字
如果是一個 div
,如果想達到這樣的效果,可能需要
- 為了使
div
聚焦,需要新增tabindex=0
屬性 - 為了使
div
被識別成按鈕,需要新增role="button"
屬性
有時候還有更極端的情況,直接使用背景圖作為按鈕,沒有文字,還需要以下操作
- 為了使
div
能夠被識別內容,需要新增aria-label
屬性
<div tabindex="0" role="button" aria-label="登入2">登入</div>
這樣螢幕閱讀基本就能正常訪問了
沒錯,文章開頭的做法就是這樣的,再來回顧一下這些茫茫多的屬性
既然要這麼麻煩,為何不直接用 button
呢?
六、為何不使用button
呢
以下是我個人的一些猜想
button
在各個瀏覽器的樣式表現不一致button
不能包含某些標籤或者會導致無效,比如a
標籤- 歷史原因,以前就用
div
實現了,不想折騰 - 不知道
button
有這麼多好用的特性 - 不在乎這些,能實現就行,我的
js
非常強 - 實際專案中不需要鍵盤訪問或者螢幕閱讀
- 某些第三方元件庫的封裝
七、總結和說明
以上從樣式和功能上介紹了原生 button
元素的幾個特性,同時還猜想了一些沒有使用button
的原因,下面總結一下:
button
支援禁用特性,通過:disabled
偽類自定義禁用樣式button
預設盒子模型是border-box
button
內預設水平垂直居中button
支援鍵盤訪問,在聚焦狀態下可以通過enter
或者space
觸發點選事件button
鍵盤聚焦的outline
可以通過outline-color
修改顏色,也可以通過:focus-visible
自定義鍵盤聚焦樣式button
在表單中支援enter
提交表單button
在表單中有重置功能button
預設支援螢幕閱讀
雖然有這麼多好用的特性,但是實際開發中還是有很多原因沒有使用。不過不管以前如何如何,從現在開始,只要碰到"按鈕",第一優先選擇button
就可以了,不用做過多修飾,就能在不知不覺中提升使用者體驗。最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤