フォームの送信ボタンや、JavaScript で動かすボタンを作るときに使うのが <button> 要素です。一見シンプルですが、type 属性を省略するとフォーム内では「送信ボタン」として扱われるなど、知らないと意図しない動きになる落とし穴があります。この記事では、type 属性の3つの値の違いを中心に、<button> の基本的な使い方と、よく使う属性、JavaScript との組み合わせ方までをまとめて解説します。HTML を学び始めた方や、フォーム周りの挙動に自信が持てない方を対象にしています。
目次
button要素の基本
<button> は、クリックできるボタンを作るための要素です。開始タグと終了タグの間に、ボタンに表示する内容を書きます。
<button type="button">クリックしてください</button>
似た役割の要素に <input type="button"> がありますが、こちらは空要素なので終了タグを持たず、ラベルは value 属性で指定します。両者の大きな違いは、<button> はタグの中に HTML を入れられる点です。たとえばアイコン画像とテキストを並べたり、文字の一部だけ強調したりできます。
<!-- button は中に画像や別の要素を入れられる -->
<button type="button">
<img src="cart.svg" alt="" width="16" height="16">
カートに入れる
</button>
<!-- input は value にテキストしか入れられない -->
<input type="button" value="カートに入れる">
表現の自由度が高いため、現在は <button> を使うのが一般的です。以降はこの要素を前提に解説していきます。
type属性の3つの値
<button> の挙動を決めるのが type 属性です。指定できる値は次の3つで、特にフォームの中で使うときに動きがはっきり変わります。
| type の値 | 動作 |
|---|---|
submit | 所属するフォームを送信する(既定値) |
reset | フォーム内の入力欄を初期値に戻す |
button | 標準の動作を持たない。JavaScript で処理を割り当てて使う |
submit はフォームの内容をサーバーへ送るボタン、reset は入力をクリアするボタンです。button は単体では何も起こらず、後述する JavaScript と組み合わせて「いいねを押す」「メニューを開く」といった独自の処理を実行させたいときに使います。
typeを省略するとsubmitになる落とし穴
ここが <button> で最もつまずきやすいポイントです。type 属性を書かなかった場合、その値は submit として扱われます。つまり、<form> の中に置いた type なしのボタンは、クリックするとフォームを送信してしまいます。
<form action="/search">
<input type="text" name="keyword">
<!-- type を書いていないので submit 扱い -->
<!-- クリックするとフォームが送信されてしまう -->
<button onclick="openMenu()">メニューを開く</button>
</form>
上の例では「メニューを開く」つもりのボタンが、クリックと同時にページを /search へ送信してしまい、開いたはずのメニューも画面遷移で消えてしまいます。「ボタンを押したらページが勝手にリロードされる・遷移する」という不具合の多くは、これが原因です。
送信が目的ではないボタンには、必ず type="button" を明示しましょう。逆に、フォーム送信ボタンとして使うときも、意図を分かりやすくするために type="submit" を書いておくのがおすすめです。type を省略してよい場面はほとんどありません。
3種類のボタンを並べて動きを確認する
実際に3つの type を並べたフォームのデモです。「送信」を押すとフォームが送信され、「リセット」を押すと入力欄が初期値(webool)に戻ります。「クリック」は type="button" で、JavaScript を割り当てて押した回数を数えています。コードを書き換えて挙動の違いを試してみてください。
<form class="demo-form">
<p class="demo-label">名前:<input type="text" name="username" value="webool"></p>
<div class="btn-row">
<button type="submit">送信(submit)</button>
<button type="reset">リセット(reset)</button>
<button type="button" id="countBtn">クリック(button)</button>
</div>
<p class="count">クリック回数:<span id="count">0</span></p>
</form>
.demo-form {
font-family: sans-serif;
padding: 16px;
}
.demo-label input {
padding: 4px 8px;
}
.btn-row {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin: 12px 0;
}
button {
padding: 8px 16px;
border: none;
border-radius: 6px;
background: #007bff;
color: #fff;
font-size: 14px;
cursor: pointer;
}
button[type="reset"] {
background: #6c757d;
}
button[type="button"] {
background: #28a745;
}
button:hover {
opacity: 0.85;
}
.count {
font-weight: bold;
}
// type="button" のボタンに動作を割り当てる
const btn = document.getElementById('countBtn');
const out = document.getElementById('count');
let count = 0;
btn.addEventListener('click', () => {
count++;
out.textContent = count;
});
よく使う属性
type 以外にも、<button> にはフォームの動きを細かく制御する属性があります。代表的なものをまとめます。
| 属性 | 役割 |
|---|---|
disabled | ボタンを無効化し、クリックできなくする |
name / value | 送信ボタンのとき、どのボタンが押されたかをサーバーに送る |
form | 離れた場所にあるフォームと関連付ける(フォームの id を指定) |
formaction | そのボタンで送信するときだけ送信先 URL を上書きする |
disabledで一時的に押せなくする
disabled を付けると、ボタンは灰色がかった見た目になり、クリックやキーボード操作を受け付けなくなります。「入力が完了するまで送信できないようにする」といった用途でよく使います。JavaScript からは button.disabled = false のように切り替えられます。
<button type="submit" disabled>送信</button>
nameとvalueで押されたボタンを判別する
1つのフォームに送信ボタンが複数あるとき、name と value を付けておくと、どのボタンが押されたかをサーバー側で判別できます。押されたボタンの name=value だけが送信されるしくみです。
<form action="/posts" method="post">
<textarea name="body"></textarea>
<!-- 「下書き保存」を押すと action=draft が送られる -->
<button type="submit" name="action" value="draft">下書き保存</button>
<!-- 「公開」を押すと action=publish が送られる -->
<button type="submit" name="action" value="publish">公開</button>
</form>
formとformactionで送信先を変える
form 属性に対象フォームの id を指定すると、<form> の外にあるボタンでもそのフォームを送信できます。さらに formaction を付ければ、そのボタンで送信するときだけ送信先 URL を action から上書きできます。同じ入力内容を別の処理に振り分けたいときに便利です。
<form id="entry" action="/confirm">
<input type="text" name="keyword">
</form>
<!-- フォームの外にあっても form="entry" で関連付けできる -->
<button type="submit" form="entry">確認画面へ</button>
<!-- このボタンだけ /preview に送信する -->
<button type="submit" form="entry" formaction="/preview">プレビュー</button>
JavaScriptと組み合わせる
type="button" のボタンは、JavaScript で処理を割り当てて初めて意味を持ちます。割り当て方には HTML 側に onclick 属性を書く方法と、JavaScript 側から addEventListener で登録する方法があります。
手軽なのは onclick 属性です。属性値に呼び出したい関数を書きます。
<button type="button" onclick="alert('押されました')">通知</button>
ただし、HTML とスクリプトが混ざって管理しづらくなるため、実務では addEventListener でまとめて登録する方法が好まれます。HTML 側は id やクラスを付けるだけにしておき、動作は JavaScript ファイルに分離します。
const btn = document.getElementById('saveBtn');
btn.addEventListener('click', () => {
console.log('保存処理を実行します');
});
なお、フォーム内のボタンで JavaScript の処理だけを実行したいのに、うっかり type を省略すると、前述のとおりフォーム送信が同時に起きてページが遷移してしまいます。送信したくないボタンには type="button" を付ける、という原則をここでも忘れないようにしましょう。
まとめ
<button> 要素は、type 属性で挙動が大きく変わります。submit は送信、reset は入力のクリア、button は JavaScript 用で、type を省略するとフォーム内では submit になる点が最大の注意ポイントです。送信が目的でないボタンには必ず type="button" を付けましょう。中に HTML を入れられる柔軟さや、disabled / name / value / form / formaction といった属性を押さえておけば、フォームから独自の操作ボタンまで安心して作れるようになります。