この記事を読むとわかること
- なぜボタンを button 要素で作るべきなのか、その理由
- どーーーーーしてもボタンを別の要素で作らなければいけないとき、何をすればいいか
答え
button 要素を使ったときに得られる標準動作を捨ててまで得られるメリットがないからです。
HTML の標準に従って、適切な要素を用いて開発することが重要です。
そもそも HTML (HyperText Markup Language) は、ドキュメントの構造や意味を印付けして表すためのマークアップ言語です。
ボタンにはボタンであるという印、つまり button 要素を用いるのが理にかなっています。
button 要素の特徴
button 要素は、標準でこれだけのことをやってくれます。
これが Web 画面における「ボタン」の機能であり、button 要素以外でボタンを作るには、これらを自分で実装しなければなりません。
- ボタンの見た目の提供
- ボタンにホバーしたときのカーソルの見た目
- ボタンを押したときの見た目
- フォーカス時の見た目
- フォーカス可能
- Space キー・Enter キーで操作可能
- これらのキーを操作したときに、自動で
click
イベントを発火してくれます。つまり、実装者は、click
イベントのハンドラーを設定するだけで、同時にキーボードのサポートも達成できます
- これらのキーを操作したときに、自動で
- 支援技術に対して「これはボタンである」と伝える(暗黙の button ロール)
div要素を完璧なボタンに仕立て上げてみる
押すと "button was hit!" というアラートを表示するボタンを、あえて div 要素を使って作ってみます。
この作業を通じて「こんな不毛な作業をするよりも、button 要素を使うほうが簡単だな」と思っていただければ幸いです。
<div>アラートを表示する</div>
ボタンの見た目をつける
- 普通のボタンは横に並べることができるので、
display: inline-block
を設定します。 - ボタンの見た目はいろいろなパターンを考えられますが、ここではシンプルに外枠を囲って背景色をつけます。
- 普通のボタンはラベルテキストの選択ができないので、
user-select: none
を設定します。 - ホバー時・押下時の見た目をつけます。
<div class="button">アラートを表示する</div> <style> .button { display: inline-block; border: solid 1px #000000; background-color: #dddddd; user-select: none; &:hover { background-color: #cccccc; } &:active { background-color: #eeeeee; } } </style>
結果
(まだ動きません)
フォーカス可能にする
tabindex="0"
を付与します。- フォーカスした際の見た目を追加します。
<div class="button" tabindex="0" > アラートを表示する </div> <style> .button { display: inline-block; border: solid 1px #000000; user-select: none; background-color: #dddddd; &:hover { background-color: #cccccc; } &:active { background-color: #eeeeee; } &:focus-visible { outline: solid 2px #000000; } } </style>
結果
(まだ動きません)
イベントハンドラーの追加
- クリックイベントだけでなく、keydown イベントを使って、スペースキー・エンターキーの操作も待ち受けなければいけません。
<div id="my-button" class="button" tabindex="0" > アラートを表示する </div> <script> const proc = () => { alert("button was hit!") } const btn = document.querySelector("#my-button") btn.addEventListener("click", proc) btn.addEventListener("keydown", (e) => { if (e.key === " " || e.key === "Enter") { e.preventDefault() proc() } }) </script> <style> .button { display: inline-block; border: solid 1px #000000; background-color: #dddddd; user-select: none; &:hover { background-color: #cccccc; } &:active { background-color: #eeeeee; } &:focus-visible { outline: solid 2px #000000; } } </style>
結果
(動きます)
支援技術のサポート
role="button"
を追加します。
<div id="my-button" class="button" tabindex="0" role="button" > アラートを表示する </div> <script> const proc = () => { alert("button was hit!") } const btn = document.querySelector("#my-button") btn.addEventListener("click", proc) btn.addEventListener("keydown", (e) => { if (e.key === " " || e.key === "Enter") { e.preventDefault() proc() } }) </script> <style> .button { display: inline-block; border: solid 1px #000000; background-color: #dddddd; user-select: none; &:hover { background-color: #cccccc; } &:active { background-color: #eeeeee; } &:focus-visible { outline: solid 2px #000000; } } </style>
結果
(動きます)
button要素で実装した場合
同様のボタンを button 要素で実装した場合と比較してみましょう。シンプルですね。
<button id="my-button"> アラートを表示する </button> <script> const proc = () => { alert("button was hit!") } const btn = document.querySelector("#my-button") btn.addEventListener("click", proc) </script>
結果
(動きます)
まとめ
ボタンをあえて div 要素で作成し、それを button 要素による実装と比較しました。
ご覧いただいたように、button 要素を使ったときに得られる標準動作を捨ててまで、他の要素を用いて実装するメリットはありません。
そもそも HTML (HyperText Markup Language) は、ドキュメントの構造や意味を印付けして表すためのマークアップ言語です。
ボタンにはボタンであるという印、つまり button 要素を用いるのが理にかなっています。
これに限らず、HTML の標準に従って、適切な要素を用いて開発しましょう。