177
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

ボタンは<button>で実装しよう

はじめに

<div class="button">や<a class="button">といったように、
ボタンを<button>以外で実装するのは極力避けよう、という話。

キーボード操作の問題

フォーカス

<button>と違い、<div>やhref属性のない<a>には、フォーカスがあたりません。
フォーカスをあてるためには、tabindex属性が必要です。

<div class="button" tabindex="0">
<a class="button" tabindex="0">

ENTERキー/SPACEキーを押した時の処理

<button>にフォーカスしてENTERキー/SPACEキーを押すと、clickイベントが発火します。
このため、<button>の場合は、clickイベントハンドラを実装しさえすれば
キーボードでボタンを押すことができます。

<div>やhref属性のない<a>の場合、このような気の利いた処理は行われないため、
自分でkeyupイベントハンドラを実装する必要があります。1

function handleClick() {
  //ボタンが押された時の処理
}

function handleKeyUp() {
  if (押されたのはENTERキーかSPACEキー?) {
    if (ボタンにフォーカスしている?) {
      //ボタンが押された時の処理
    }
}

スクリーンリーダーの問題

スクリーンリーダー(視覚障害者の方などが使う音声読み上げソフト)は、<button>を、その要素が「ボタン」だとわかるように読み上げます。
例えば、以下の内容をスクリーンリーダー(ここではNVDA)で読み上げると、「保存、ボタン」と読み上げられます。

<button>保存</button>

<div>や<a>で実装した場合、ブラウザは、その要素が「ボタン」であると解釈できないため、
「ボタン」と読み上げません。<a>に至っては「リンク」と読み上げてしまいます。
「ボタン」と読み上げるようにするには、role="button"をつける必要があります。

<div class="button" tabindex="0" role="button">保存</div>

<button type="button">を使おう

フォームと連動することを理由に、<button>を敬遠する人もいます。
<button>のtype属性には、submitやresetの他に、buttonという属性値が用意されており、
これを指定すると、フォームに対して何もしないボタンを作ることができます。2

<button type="button">保存</button>

type="button"については「コーディングWebアクセシビリティ」という書籍でも
解説されているので、一読されることをおすすめします。

まとめ

ボタンは<button>で実装しましょう。
もし<div>や<a>で実装する場合、<button>と同じ動きをさせるには、以下の対応が必要です。

  • tabindex="0"をつける
  • keyupイベントハンドラを実装する
  • role="button"をつける

  1. mozillaのdeveloperサイトにも、キーボード操作を自力で実装する必要性が解説されています。 

  2. HTML5仕様書にも「Does Nothing」と明記されています。 

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
177
Help us understand the problem. What are the problem?