概要
HTMLフォームで最も多く使われる要素の一つ、<button>
タグ。
しかし、このタグを何も指定せずに使うことがバグの原因になると知っている開発者は意外と少ない。
実は <button>
は type
属性を明示しないと、自動的に type="submit"
として振る舞う。
この挙動により、「ボタンを押しただけでフォームが送信される」「JSのイベントが阻害される」など、意図しない副作用が発生することがある。
本記事では、<button>
タグにおける type
のデフォルト動作、ユースケースごとの正しい指定方法、よくある落とし穴とその回避策を体系的に解説する。
対象環境
HTML5対応のすべてのブラウザ
(Chrome / Firefox / Safari / Edge ほか)
なぜ type
を明示するべきなのか?
<button>クリック</button>
このコードは、見た目には問題ないが、実際には type="submit"
として解釈される。
つまり、このボタンが <form>
の内部にある場合、押すとフォームが送信される。
意図的に「送信ボタン」として作っていない場合、これは明確なバグである。
<button>
の3つの type
値と意味
type | 説明 |
---|---|
submit |
フォームを送信する(デフォルト動作) |
reset |
フォーム内のすべての入力値をリセット |
button |
何もしない。JavaScriptのトリガー用途に使う場合はこれを明示すべき |
使用例:意図しない送信が発生するケース
<form onsubmit="alert('送信されました')">
<button onclick="console.log('クリック')">押すな</button>
</form>
この場合、ボタンをクリックすると:
-
console.log('クリック')
が実行され - フォームが
submit
されて -
alert('送信されました')
が表示される
→ ボタンに type="button"
を指定していれば、送信は起きなかった
正しく防ぐ書き方
<form>
<button type="button" onclick="console.log('実行')">実行ボタン</button>
</form>
このように、JSによる処理だけをしたい場合は type="button"
を明示することで、送信を防げる。
reset
はいつ使うべきか?
<button type="reset">リセット</button>
- 入力フォーム全体を初期状態に戻したいときに使う
- JavaScriptなしで一括リセットが可能
- あまり使われないが、入力補助系UIでは便利
Reactなどのフレームワークでも同様
たとえばReactにおいても、以下のように指定しないと意図せずsubmitされてしまう。
<button onClick={handleClick}>処理</button> // ← デフォルトで type="submit"
正しくは:
<button type="button" onClick={handleClick}>処理</button>
よくあるミスとその代償
- 「モーダルを開くボタン」が押された瞬間に画面がリロードされる
- 「JavaScriptだけのトリガー」が
form.submit()
を引き起こす -
e.preventDefault()
を書き忘れたイベントが暴走する
どれも「typeを書かなかっただけ」で起きる不具合だ。
結語
<button>
タグは、その用途によって「明示的に意味を与える」必要がある要素である。
フォーム送信用なのか、リセットなのか、単なるJSのトリガーなのか。
その意図を type
で言語化することで、予期せぬバグを未然に防ぎ、意図が明確なコードを実現できる。
HTMLは「書けば動く」ではない。
書き方が伝える意味こそが、バグのないプロダクトを支えている。