送信ボタン

button type=submit button type=button button type=reset input type=submit

フォームの送信には <button type="submit"> を使います。type 属性を必ず明示することで、意図しないフォーム送信を防げます。 現代では HTML コンテンツを内包できる button 要素が推奨されます。

デモ: button の各 type

{/* フォームを送信 — HTML5 バリデーションも実行 */}
<button type="submit">送信</button>

{/* フォーム送信しない — JS処理に使う */}
<button type="button" onClick={handleCancel}>キャンセル</button>

{/* フォームの全フィールドを初期値にリセット */}
<button type="reset">リセット</button>

formaction / formmethod 属性

formactionformmethod を使うと、 同じフォーム内の複数の送信ボタンで異なる送信先・メソッドを指定できます。 form 要素の action / method を上書きします。

<form action="/api/default" method="post">
  <input type="text" name="title" />

  {/* form の action を上書き */}
  <button
    type="submit"
    formAction="/api/save-draft"
    formMethod="post"
  >
    下書き保存
  </button>

  {/* 別のエンドポイントに送信 */}
  <button
    type="submit"
    formAction="/api/publish"
    formMethod="post"
  >
    公開する
  </button>
</form>

input[type=submit] vs button[type=submit]

input type="submit"
button type="submit"
{/* 旧来の方法: テキストのみ、value で表示テキストを設定 */}
<input type="submit" value="送信" />

{/* 推奨: HTML コンテンツを内包できる */}
<button type="submit">
  <svg>...</svg>
  送信
</button>

form.requestSubmit() — プログラムによる送信

form.requestSubmit() はフォームをプログラムから送信するモダンな方法です。form.submit() と異なり、HTML5 バリデーション(required, pattern 等)を実行してから送信します。

"use client";
// form.submit() — バリデーションをスキップして即送信(非推奨)
document.querySelector("form").submit();

// form.requestSubmit() — バリデーションを実行してから送信(推奨)
const form = document.querySelector("form");
form.requestSubmit(); // バリデーション失敗時は送信しない

// 特定の submit ボタンを指定して送信(formaction等も反映)
const submitBtn = document.querySelector("button[type='submit']");
form.requestSubmit(submitBtn);

// React での使用例
const formRef = useRef<HTMLFormElement>(null);
function handleProgrammaticSubmit() {
  formRef.current?.requestSubmit();
}

<form ref={formRef}>
  <input type="text" required />
  <button type="button" onClick={handleProgrammaticSubmit}>
    外部トリガーで送信
  </button>
</form>

button vs input[type=submit] 比較

比較項目button type="submit"input type="submit"
HTML コンテンツ可(SVG、アイコン等を内包できる)不可(value でテキストのみ)
CSS スタイリング柔軟(擬似要素 ::before/::after 使用可)やや制限あり
value 属性送信データとして使えるボタンのラベルになる
formaction対応対応
推奨度現代では推奨後方互換性のために存在

Tips

  • 必ず type 属性を明示する — form 内の button は type 省略時に type="submit" がデフォルトになり、意図しないフォーム送信が起きる
  • JS 処理のみのボタンには type="button" を明示する(モーダルを開く、タブ切り替えなど)
  • form.requestSubmit() は HTML5 バリデーションを実行するため、form.submit() よりも安全
  • button の内部に SVG アイコンを入れる場合、アイコンに aria-hidden="true" を付け、ボタンには aria-label を設定してアクセシビリティを確保する
  • 二重送信防止には、送信後に disabled にするか、React 19 の useFormStatus フックを活用する

🤖 AIプロンプトテンプレート

以下について、AIへの質問プロンプト例を示します。

- `<button>` の `type` 属性を省略すると `type="submit"` になる理由と、意図しない送信を防ぐベストプラクティスを教えてください。
- `<button type="submit">` と `<input type="submit">` の違いと、現代で `button` が推奨される理由を教えてください。
- `form.requestSubmit()` と `form.submit()` の違いと、HTML5 バリデーションとの関係を教えてください。
- `formaction` / `formmethod` 属性を使って、同じフォーム内の複数のボタンで異なるエンドポイントに送信する方法を教えてください。
- 二重送信を防ぐための実装方法(disabled 化・React 19 の useFormStatus 等)を教えてください。

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。