1. ホーム
  2. HTML

【HTML】button要素の使い方|type属性(submit・reset・button)の違いを解説

Share

フォームの送信ボタンや、JavaScript で動かすボタンを作るときに使うのが <button> 要素です。一見シンプルですが、type 属性を省略するとフォーム内では「送信ボタン」として扱われるなど、知らないと意図しない動きになる落とし穴があります。この記事では、type 属性の3つの値の違いを中心に、<button> の基本的な使い方と、よく使う属性、JavaScript との組み合わせ方までをまとめて解説します。HTML を学び始めた方や、フォーム周りの挙動に自信が持てない方を対象にしています。

button要素の基本

<button> は、クリックできるボタンを作るための要素です。開始タグと終了タグの間に、ボタンに表示する内容を書きます。

index.html
<button type="button">クリックしてください</button>

似た役割の要素に <input type="button"> がありますが、こちらは空要素なので終了タグを持たず、ラベルは value 属性で指定します。両者の大きな違いは、<button> はタグの中に HTML を入れられる点です。たとえばアイコン画像とテキストを並べたり、文字の一部だけ強調したりできます。

index.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 なしのボタンは、クリックするとフォームを送信してしまいます。

index.html
<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;
});
Preview

よく使う属性

type 以外にも、<button> にはフォームの動きを細かく制御する属性があります。代表的なものをまとめます。

属性役割
disabledボタンを無効化し、クリックできなくする
name / value送信ボタンのとき、どのボタンが押されたかをサーバーに送る
form離れた場所にあるフォームと関連付ける(フォームの id を指定)
formactionそのボタンで送信するときだけ送信先 URL を上書きする

disabledで一時的に押せなくする

disabled を付けると、ボタンは灰色がかった見た目になり、クリックやキーボード操作を受け付けなくなります。「入力が完了するまで送信できないようにする」といった用途でよく使います。JavaScript からは button.disabled = false のように切り替えられます。

index.html
<button type="submit" disabled>送信</button>

nameとvalueで押されたボタンを判別する

1つのフォームに送信ボタンが複数あるとき、namevalue を付けておくと、どのボタンが押されたかをサーバー側で判別できます。押されたボタンの name=value だけが送信されるしくみです。

index.html
<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 から上書きできます。同じ入力内容を別の処理に振り分けたいときに便利です。

index.html
<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 属性です。属性値に呼び出したい関数を書きます。

index.html
<button type="button" onclick="alert('押されました')">通知</button>

ただし、HTML とスクリプトが混ざって管理しづらくなるため、実務では addEventListener でまとめて登録する方法が好まれます。HTML 側は id やクラスを付けるだけにしておき、動作は JavaScript ファイルに分離します。

main.js
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 といった属性を押さえておけば、フォームから独自の操作ボタンまで安心して作れるようになります。

参考ページ