世界を動かす技術を、日本語で。

ボタンを使うだけで

2025年11月1日原文(gomakethings.com)

概要

  • <div><button> の使い分けに関する誤解の指摘
  • アクセシビリティの観点から <button> が優れている理由の解説
  • role属性tabindex による“修正”の問題点
  • キーボード操作やスクリーンリーダー対応の重要性
  • 最終的に button要素 を使うべき理由のまとめ

フレームワーク開発者が陥りがちな「divとbuttonは同じ」論争

  • ReactやHTMXユーザーの間で <div> をボタン代わりに使う事例の多発
    • 例: <div onclick="showSignIn()"> Open Modal </div>
  • この実装では スクリーンリーダー 利用者に対して操作可能要素であることが伝わらない
  • キーボード操作 (Tab移動やEnter/Space押下)に非対応
  • 著名なReact界隈の人物が「divがbuttonよりアクセシブル」と主張した事例も存在

「修正案」が抱える根本的な問題

  • HTMLの button要素 は暗黙的に[role="button"]を持ち、支援技術に意図が伝わる
  • role属性 をdivに付与しても、フォーカス可能やキーボード操作には非対応
    • 例: <div role="button" onclick="showSignIn()"> Open Modal </div>
  • tabindex="0" でフォーカス可能にできるが、フォーカス順序の混乱や予期せぬ動作を招くリスク
    • 例: <div onclick="showSignIn()" tabindex="0"> Open Modal </div>
  • キーボード操作対応には keydownイベント の追加実装が必要
    • Enter/Space押下時だけ処理するよう分岐
    • フォーカス対象の特定やイベントの伝播制御が煩雑

「全部自作」するくらいなら最初からbuttonを使うべき理由

  • 上記の「修正」を積み重ねると、結局buttonの標準機能を再実装しているだけ
  • button要素なら…
    • role="button" が自動で付与される
    • Tabキー で自然にフォーカス移動
    • Enter/Space で自動的にクリックイベント発火
  • 余計なコードを書く必要がなく、保守性・アクセシビリティ・ユーザビリティ全てで優位

結論:正しい要素を選ぶことが最良の“省力化”

  • Reactや他のフレームワークが好きな開発者ほど、 「書かなくて済むコード」 を重視する傾向
  • button要素 を正しく使うことで、無駄な実装やバグの温床を回避
  • 本質的なアクセシビリティ開発効率 の両立が実現

Hackerたちの意見

変だな、ボタンが使えるときはいつもボタン使うんだけど、必要なものが実際にはボタンじゃなくて、ボタンみたいに動く何か、例えばウェブアプリ内を移動するハイパーリンクみたいなものだったら別だけど。

URLが更新されないなら、それはボタンだと思う。URLが変わるなら、リンクにすべきだね。少なくとも、俺はいつもそうしてる。

ウェブアプリをナビゲートするハイパーリンクみたいなもの? それって <a> タグのこと?

100% 元の意図にできるだけ近い要素を使うべきだよね。

そもそも、なんで誰かがそのオプションを提案するの?

世界を見てると、理由の一つはボタンに変な見た目を適用しやすくするからだと思う。だから、ボタンとして機能しないだけじゃなくて、見た目もボタンじゃなくなっちゃうんだよね。

ところで、TV Tropesって知ってる? あそこには長いリストがあって、1ページ内で「フォルダ」に分かれてるんだ。 その「フォルダ」をクリックすると展開したり折りたたんだりできるんだけど、これは「onclick」プロパティを使った実装で、内部には(昔はそうだったと思うけど、今は兄弟の子供みたいな感じだね)。

一番よく見る理由は、デフォルトのボタンスタイルをオーバーライドしなきゃいけないって愚痴だね。

この記事に追加しておきたいのは、ほとんどのボタンにはtype="button"を設定すべきってこと。デフォルトではボタンはtype="submit"になってて、フォーム内にあるとそのフォームを送信しちゃうんだ。送信動作を無効にする正しい方法を知らない開発者がdivを使っちゃうこともあるだろうけど。

そうだね。苦労して学んだよ、笑

彼らは送信動作を無効にする正しい方法を知らない。これはDIVの利点で、知らないからtype="submit"を誤って設定することがない。多くの人が知らないことはたくさんあるよね。DIVを使うと、空の状態から始めて、追加したい機能を明示的に加えることができるから、後でその機能を簡単に削除したり変更したりできるんだ。もちろん、HTMLの標準についての知識が豊富で、Buttonが現在のユースケースにぴったり合うなら使うだろうけど、デザインや要件は常に変わるからね。DIVを使うことでデザインがより透明になるし、属性を追加することで設定した機能が見えるようになる。Buttonを使うと、あなたやコードを読む他の人が、何をするのかを理解するためにドキュメントを参照したくなるかもしれないけど、DIV + 属性ならそれが明示的に「書かれている」んだ。いくつかの利点と欠点だね。

デフォルトは、のためのものであって、ではないと信じてる。

Hacker Newsで議論の続きを見る