【HTML】formタグの使い方:属性の書き方や複数送信・CSS装飾

html-form-tag

Webサイトにお問い合わせや登録機能を持たせる不可欠なHTMLの<form>タグですが、属性の指定漏れやレイアウトの組み方など初心者が陥りやすいものが多数存在します。

本記事では、基本の書き方からCSSによる横並びデザイン、JS/PHPとのデータ連携、実務で必須になる「Enterキー誤送信防止」など解説します。

目次

form(フォーム)タグの役割と書き方

Webサイトにお問い合わせページやログイン画面・アンケート機能を作る際、ユーザーが入力したデータを集めてサーバーに送信する「箱」の役割を果たすのが<form>(フォーム)タグです。

本記事では、フォームの役割や書き方まで解説します。

form(フォーム)タグの役割と書き方
  • formタグの役割と必須属性
  • フォームを構成する部品・タグ一覧

formタグの役割と必須属性

<form>タグは画面に何かを表示するものではありません。

その中に配置された入力欄のデータをまとめ、「どこに」「どうやって」送るかを指定する見えないラッパーです。

ユーザーからデータを受け取る入力部品は、<form>タグで囲みます。

そして、<form>タグには以下の2つの属性をセットで書くのがルールです。

  1. action属性:データの送信先URL(例:action="/send.php"
  2. method属性:データの送信方式(基本はmethod="POST"またはmethod="GET"
📦 formタグの基本構造
<!– formタグで全体を囲む(必須) –>
<form action=”/contact.php” method=”POST”>

  <label>お名前</label>
  <input type=”text” name=”user_name”>

  <button type=”submit”>送信する</button>

</form>

※actionにはデータの送り先を、methodには送り方(個人情報などは中身が隠れるPOST)を指定します。

HTMLコード表示
<div class="hform-base-wrapper">
  
  <div class="hform-base-demo-area">
    
    <div class="hform-base-box">
      <div class="hform-base-label">📦 formタグの基本構造</div>
      
      <div class="hform-base-visual">
        <form action="#" method="POST" onsubmit="event.preventDefault(); alert('送信処理が走りました!(デモ)');">
          <div class="hform-base-group">
            <label>お名前</label>
            <input type="text" placeholder="山田 太郎" required>
          </div>
          <button type="submit" class="hform-base-btn">送信する</button>
        </form>
      </div>

      <div class="hform-base-code">
        <!-- formタグで全体を囲む(必須) --><br>
        <span class="hform-base-hl-blue"><form</span> <span class="hform-base-hl-green">action="/contact.php"</span> <span class="hform-base-hl-green">method="POST"</span><span class="hform-base-hl-blue">></span><br><br>
          <label>お名前</label><br>
          <input type="text" name="user_name"><br><br>
          <button type="submit">送信する</button><br><br>
        <span class="hform-base-hl-blue"></form></span>
      </div>
      <p class="hform-base-note">※actionにはデータの送り先を、methodには送り方(個人情報などは中身が隠れるPOST)を指定します。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-base-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-base-demo-area {
  display: flex;
  justify-content: center;
}
.hform-base-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-base-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #333; }

.hform-base-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hform-base-group {
  margin-bottom: 15px;
}
.hform-base-group label {
  display: block;
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 5px;
  color: #555;
}
.hform-base-group input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
  font-size: 14px;
}
.hform-base-btn {
  width: 100%;
  padding: 12px;
  background-color: #0d6efd;
  color: white;
  border: none;
  border-radius: 4px;
  font-weight: bold;
  cursor: pointer;
  font-size: 14px;
}
.hform-base-btn:hover { background-color: #0b5ed7; }

.hform-base-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hform-base-hl-blue { color: #61afef; font-weight: bold; }
.hform-base-hl-green { color: #98c379; font-weight: bold; }
.hform-base-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

フォームを構成する部品・タグ一覧

<form>という箱の中には、用途に合わせて入力用タグを配置します。

  • <input>
    1行テキスト、パスワード、ラジオボタン、チェックボックスなど、様々な種類を作れるタグ。
  • <textarea>
    お問い合わせ内容など、複数行の長文を入力するタグ。
  • <select>
    都道府県など、ドロップダウンリストから選択させるタグ。
❌ 悪い例(配慮のない実装)
<!– 文字を押してもチェックされない! –>
<input type=”checkbox”>
<label>利用規約に同意する</label>
⭕️ 良い例(正しいタグと紐付け)
<!– idとforを同じ名前でつなぐ –>
<input type=”checkbox” id=”terms”>
<label for=”terms”>利用規約に同意</label>
HTMLコード表示
<div class="hform-parts-wrapper">
  
  <div class="hform-parts-demo-area">
    
    <div class="hform-parts-box">
      <div class="hform-parts-label" style="color:#dc3545;">❌ 悪い例(配慮のない実装)</div>
      
      <div class="hform-parts-visual">
        <div class="hform-parts-group">
          <label>メールアドレス</label>
          <input type="text" placeholder="typeをtextでサボっている" class="hform-parts-input">
        </div>
        
        <div class="hform-parts-group">
          <input type="checkbox"> <label>利用規約に同意する(文字を押しても無反応)</label>
        </div>
      </div>

      <div class="hform-parts-code hform-parts-code-bad">
        <!-- 文字を押してもチェックされない! --><br>
        <input type="checkbox"><br>
        <label>利用規約に同意する</label>
      </div>
    </div>

    <div class="hform-parts-box">
      <div class="hform-parts-label" style="color:#198754;">⭕️ 良い例(正しいタグと紐付け)</div>
      
      <div class="hform-parts-visual">
        <div class="hform-parts-group">
          <label>メールアドレス</label>
          <input type="email" placeholder="type='email'を指定" class="hform-parts-input" style="border-color:#198754;">
        </div>

        <div class="hform-parts-group">
          <label>ご用件</label>
          <select class="hform-parts-input">
            <option>選択してください</option>
            <option>ご質問</option>
            <option>お見積り</option>
          </select>
        </div>
        
        <div class="hform-parts-group" style="background-color: #d1e7dd; padding: 10px; border-radius: 4px;">
          <input type="checkbox" id="terms-check"> 
          <label for="terms-check" style="display:inline; cursor:pointer; font-weight:bold; color:#0f5132;">利用規約に同意する(文字を押せる!)</label>
        </div>
      </div>

      <div class="hform-parts-code hform-parts-code-good">
        <!-- idとforを同じ名前でつなぐ --><br>
        <input type="checkbox" <span class="hform-parts-hl-green">id="terms"</span>><br>
        <label <span class="hform-parts-hl-green">for="terms"</span>>利用規約に同意</label>
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hform-parts-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-parts-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hform-parts-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-parts-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hform-parts-visual {
  margin-bottom: 15px;
}
.hform-parts-group {
  margin-bottom: 15px;
}
.hform-parts-group label {
  display: block;
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 5px;
  color: #333;
}
.hform-parts-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
  font-size: 14px;
}
select.hform-parts-input {
  cursor: pointer;
}

.hform-parts-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hform-parts-code-bad { border-left: 4px solid #dc3545; }
.hform-parts-code-good { border-left: 4px solid #198754; }
.hform-parts-hl-green { color: #98c379; font-weight: bold; }

inputタグの使い方を詳しく知りたい人は「【HTML】inputタグの使い方:type種類・属性一覧とCSS装飾・JS連携」を一読ください。

formタグの重要属性:action・method・enctype

HTMLでフォームの見た目を作れても、それだけでデータは送信されません。

フォームをシステムとして稼働させるには、<form>タグに付与する3つの重要属性を理解する必要があります。

ここでは、データの送り先を決めるaction、送り方を決めるmethod、ファイルを送るenctypeについて解説します。

formタグの重要属性
  • データの送信先を指定するaction属性
  • 送信方法を決めるmethod属性
  • ファイルアップロードのenctype属性

データの送信先を指定するaction属性

action属性は、ユーザーが入力したデータを「どのURLに向けて送信するか」を指定する属性です。

宛先の指定方法は、リンク(<a>タグ)と同じように、https://...から始まる絶対パスや/contact/send.phpのような「相対パス」を使用します。

⭕️ 正しい指定(別のURLへ送信)
<!– 宛先(URLやパス)をしっかり書く –>
<form action=”/api/send-data”>
  …
</form>
❌ 省略・空指定(自分自身に送信)
<!– 省略すると現在のURLに送信(リロード)される –>
<form action=””>
  …
</form>
HTMLコード表示
<div class="hform-attr1-wrapper">
  
  <div class="hform-attr1-demo-area">
    
    <div class="hform-attr1-box">
      <div class="hform-attr1-label" style="color:#198754;">⭕️ 正しい指定(別のURLへ送信)</div>
      
      <div class="hform-attr1-visual">
        <form action="/api/send-data" method="POST" onsubmit="event.preventDefault(); alert('「/api/send-data」へデータを送信しました!');">
          <input type="text" placeholder="お名前" class="hform-attr1-input">
          <button type="submit" class="hform-attr1-btn">送信する</button>
        </form>
      </div>

      <div class="hform-attr1-code hform-attr1-code-good">
        <!-- 宛先(URLやパス)をしっかり書く --><br>
        <form <span class="hform-attr1-hl-green">action="/api/send-data"</span>><br>
          ...<br>
        </form>
      </div>
    </div>

    <div class="hform-attr1-box">
      <div class="hform-attr1-label" style="color:#dc3545;">❌ 省略・空指定(自分自身に送信)</div>
      
      <div class="hform-attr1-visual">
        <form action="" method="POST" onsubmit="event.preventDefault(); alert('自分自身(現在のページ)をリロードしました。');">
          <input type="text" placeholder="お名前" class="hform-attr1-input">
          <button type="submit" class="hform-attr1-btn" style="background-color:#dc3545;">送信する</button>
        </form>
      </div>

      <div class="hform-attr1-code hform-attr1-code-bad">
        <!-- 省略すると現在のURLに送信(リロード)される --><br>
        <form <span class="hform-attr1-hl-red">action=""</span>><br>
          ...<br>
        </form>
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hform-attr1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-attr1-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hform-attr1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-attr1-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hform-attr1-visual {
  margin-bottom: 15px;
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
}
.hform-attr1-input {
  width: 100%;
  padding: 10px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}
.hform-attr1-btn {
  width: 100%;
  padding: 10px;
  background-color: #198754;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: bold;
}

.hform-attr1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hform-attr1-code-good { border-left: 4px solid #198754; }
.hform-attr1-code-bad { border-left: 4px solid #dc3545; }
.hform-attr1-hl-green { color: #98c379; font-weight: bold; }
.hform-attr1-hl-red { color: #e06c75; font-weight: bold; }

送信方法を決めるmethod属性

method属性は、データを「どのような方法で運ぶか」を指定します。

実務で使われるのは以下の2種類です。

  • GET:データをURLの末尾にくっつけて送る方法。
    • URLに残るため、検索結果のページをブックマークしたり、他人にシェアできるのがメリットです。
  • POST:データを見えない裏側に隠して送る方法。
    • URLには一切表示されないため、個人情報や長文の送信に必須です。

「検索バー」のように、URLが変わっても困らない・シェアしたい機能にはGETを使います。

それ以外の「個人情報、パスワード、お問い合わせ内容、決済情報」などは、POSTを指定してください。

※なお、現在の開発ではフォームの画面遷移を嫌うため、formタグを使わずにJavaScriptを使ってPOST送信する手法も主流になっています。

🔍 検索バー(method=”GET”)
URL: https://…/search?q=HTML入門
<!– 検索はURLに残してシェアできるようにGET –>
<form action=”/search” method=”GET”>
  <input type=”text” name=”q”>
</form>
🔐 ログイン画面(method=”POST”)
URL: https://…/login (※パスワードは隠される)
<!– 個人情報は絶対にURLに出さないようPOST –>
<form action=”/login” method=”POST”>
  <input type=”password” name=”pw”>
</form>
HTMLコード表示
<div class="hform-attr2-wrapper">
  
  <div class="hform-attr2-demo-area">
    
    <div class="hform-attr2-box">
      <div class="hform-attr2-label" style="color:#0d6efd;">🔍 検索バー(method="GET")</div>
      
      <div class="hform-attr2-visual">
        <label style="font-size:12px; font-weight:bold; color:#666;">キーワード検索</label>
        <input type="text" value="HTML入門" class="hform-attr2-input">
        
        <div class="hform-attr2-url-bar">
          URL: https://.../search<span class="hform-attr2-hl-blue">?q=HTML入門</span>
        </div>
      </div>

      <div class="hform-attr2-code">
        <!-- 検索はURLに残してシェアできるようにGET --><br>
        <form action="/search" <span class="hform-attr2-hl-blue">method="GET"</span>><br>
          <input type="text" name="q"><br>
        </form>
      </div>
    </div>

    <div class="hform-attr2-box">
      <div class="hform-attr2-label" style="color:#d63384;">🔐 ログイン画面(method="POST")</div>
      
      <div class="hform-attr2-visual">
        <label style="font-size:12px; font-weight:bold; color:#666;">パスワード</label>
        <input type="password" value="mySecretPw!" class="hform-attr2-input">
        
        <div class="hform-attr2-url-bar">
          URL: https://.../login <span style="color:#999;">(※パスワードは隠される)</span>
        </div>
      </div>

      <div class="hform-attr2-code" style="border-left-color: #d63384;">
        <!-- 個人情報は絶対にURLに出さないようPOST --><br>
        <form action="/login" <span class="hform-attr2-hl-pink">method="POST"</span>><br>
          <input type="password" name="pw"><br>
        </form>
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hform-attr2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-attr2-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hform-attr2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-attr2-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hform-attr2-visual {
  margin-bottom: 15px;
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
}
.hform-attr2-input {
  width: 100%;
  padding: 8px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}
.hform-attr2-url-bar {
  background-color: #e9ecef;
  padding: 8px;
  font-size: 12px;
  font-family: monospace;
  color: #333;
  border-radius: 20px;
  border: 1px solid #ced4da;
}

.hform-attr2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hform-attr2-hl-blue { color: #61afef; font-weight: bold; }
.hform-attr2-hl-pink { color: #c678dd; font-weight: bold; }

ファイルアップロードのenctype属性

履歴書のPDFやプロフィール用画像など、ファイルをサーバーに送信したい時のみ登場する特殊属性がenctypeです。

フォームの中に<input type="file">が1つでも存在する場合は、<form>タグにmethod="POST"enctype="multipart/form-data"の2つをセットで記述するのがルールです。

📁 ファイルアップロード
<!– fileがある時は必要 –>
<form action=”/upload” method=”POST” enctype=”multipart/form-data”>

  <input type=”file” name=”profile_img”>
  <button type=”submit”>アップロード</button>

</form>

※この enctype の指定を忘れると、画像データではなく「画像の名前のテキスト」しか送信されず、裏側のシステムでエラーになります。

HTMLコード表示
<div class="hform-attr3-wrapper">
  
  <div class="hform-attr3-demo-area">
    
    <div class="hform-attr3-box">
      <div class="hform-attr3-label">📁 ファイルアップロード</div>
      
      <div class="hform-attr3-visual">
        <label style="font-size:12px; font-weight:bold; color:#666;">プロフィール画像を選択</label>
        <div style="padding:15px; border:1px solid #ccc; background:#fff; border-radius:4px; margin-top:5px;">
          <input type="file" id="hform-attr3-file">
        </div>
      </div>

      <div class="hform-attr3-code">
        <!-- fileがある時は必要 --><br>
        <form action="/upload" <span class="hform-attr3-hl-yellow">method="POST"</span> <span class="hform-attr3-hl-pink">enctype="multipart/form-data"</span>><br><br>
          <input type="file" name="profile_img"><br>
          <button type="submit">アップロード</button><br><br>
        </form>
      </div>
      <p class="hform-attr3-note">※この <code>enctype</code> の指定を忘れると、画像データではなく「画像の名前のテキスト」しか送信されず、裏側のシステムでエラーになります。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-attr3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-attr3-demo-area {
  display: flex;
  justify-content: center;
}
.hform-attr3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hform-attr3-label { font-size: 15px; font-weight: bold; margin-bottom: 15px; color: #333; }

.hform-attr3-visual {
  margin-bottom: 15px;
  padding: 15px;
  background-color: #f1f3f5;
  border-radius: 4px;
}

.hform-attr3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #e5c07b;
}
.hform-attr3-hl-yellow { color: #e5c07b; font-weight: bold; }
.hform-attr3-hl-pink { color: #c678dd; font-weight: bold; }
.hform-attr3-note { font-size: 12px; color: #dc3545; font-weight: bold; margin-top: 10px; line-height: 1.5; }

使いやすいフォームを作る:デザインとレイアウト

HTMLのタグを並べただけの初期状態のフォームは、使いにくくユーザーに入力するのが面倒くさいと思わせてしまいます。

離脱率を下げるには、CSSを使って直感的なデザインに整えることが不可欠です。

ここでは、実務で求められる項目と入力欄の横並びレイアウトや、スマホ対応を見据えた幅やサイズの調整方法、フォーム全体を見やすくする背景の設定について解説します。

使いやすいフォームを作る
  • 項目と入力欄を横並びに配置
  • プレースホルダーや入力幅の調整

項目と入力欄を横並びに配置

PC向けのフォームでは、「お名前」「メールアドレス」といった項目名を左側に、入力欄を右側に横並びで配置するレイアウトが定番です。

横並びレイアウトは、display: flex;(Flexbox)を使用します。

項目と入力欄を一つの<div>(グループ)で囲み、display: flex;をかけるだけで簡単に揃います。

さらに要素間の隙間もgapプロパティでコントロールできます。

📏 Flexboxによる横並びフォーム
/* 1行分のグループをFlexboxにする */
.form-group {
  display: flex;
  align-items: center; /* 縦のズレを中央で揃える */
  gap: 20px; /* 項目と入力欄の隙間 */
}

/* スマホ(画面幅500px以下) */
@media (max-width: 500px) {
  .form-group {
    flex-direction: column; /* 縦並びに変更! */
    align-items: flex-start; /* 左寄せにする */
  }
}

※ブラウザの幅を狭くしてみてください。テーブルタグでは不可能な「スマホでの自然な縦並び」がFlexboxなら一瞬で実現できます。

HTMLコード表示
<div class="hform-layout1-wrapper">
  
  <div class="hform-layout1-demo-area">
    
    <div class="hform-layout1-box">
      <div class="hform-layout1-label">📏 Flexboxによる横並びフォーム</div>
      
      <div class="hform-layout1-visual">
        <form>
          <div class="hform-layout1-group">
            <label class="hform-layout1-title">会社名</label>
            <div class="hform-layout1-input-area">
              <input type="text" placeholder="株式会社〇〇" class="hform-layout1-input">
            </div>
          </div>
          
          <div class="hform-layout1-group">
            <label class="hform-layout1-title">お名前 <span class="hform-layout1-req">必須</span></label>
            <div class="hform-layout1-input-area">
              <input type="text" placeholder="山田 太郎" class="hform-layout1-input">
            </div>
          </div>
        </form>
      </div>

      <div class="hform-layout1-code">
        /* 1行分のグループをFlexboxにする */<br>
        .form-group {<br>
          <span class="hform-layout1-hl-green">display: flex;</span><br>
          align-items: center; /* 縦のズレを中央で揃える */<br>
          <span class="hform-layout1-hl-green">gap: 20px; /* 項目と入力欄の隙間 */</span><br>
        }<br><br>
        /* スマホ(画面幅500px以下) */<br>
        @media (max-width: 500px) {<br>
          .form-group {<br>
            <span class="hform-layout1-hl-blue">flex-direction: column;</span> /* 縦並びに変更! */<br>
            align-items: flex-start; /* 左寄せにする */<br>
          }<br>
        }
      </div>
      <p class="hform-layout1-note">※ブラウザの幅を狭くしてみてください。テーブルタグでは不可能な「スマホでの自然な縦並び」がFlexboxなら一瞬で実現できます。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-layout1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-layout1-demo-area {
  display: flex;
  justify-content: center;
}
.hform-layout1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hform-layout1-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #333; }

.hform-layout1-visual {
  background-color: #f8f9fa; /* うっすらグレーの背景 */
  padding: 25px 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}

/* ★Flexboxによる横並び設定 */
.hform-layout1-group {
  display: flex;
  align-items: center; /* 縦方向の中央揃え */
  gap: 15px; /* 項目名と入力欄の間の隙間 */
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px dotted #ccc;
}
.hform-layout1-group:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

/* 左側の項目名 */
.hform-layout1-title {
  width: 120px; /* 項目名の幅を固定して揃える */
  flex-shrink: 0; /* 画面が縮んでも項目名は縮ませない */
  font-size: 14px;
  font-weight: bold;
  color: #333;
}
/* 右側の入力エリア */
.hform-layout1-input-area {
  flex-grow: 1; /* 残りの幅をすべて埋める */
}
.hform-layout1-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  font-size: 14px;
  box-sizing: border-box;
}

/* 必須マークの装飾 */
.hform-layout1-req {
  background-color: #dc3545;
  color: white;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 3px;
  margin-left: 5px;
}

/* スマホ対応:画面が狭いと縦並びにする */
@media (max-width: 450px) {
  .hform-layout1-group {
    flex-direction: column; /* 縦に積む */
    align-items: flex-start; /* 左寄せ */
    gap: 8px; /* 縦の隙間を狭くする */
  }
  .hform-layout1-title {
    width: 100%; /* 項目名を100%にする */
  }
}

.hform-layout1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hform-layout1-hl-green { color: #98c379; font-weight: bold; }
.hform-layout1-hl-blue { color: #61afef; font-weight: bold; }
.hform-layout1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

displayプロパティの使い方を詳しく知りたい人は「【html&css】displayの種類は?flexやinline-blockの違い」を一読ください。

プレースホルダーや入力幅の調整

フォームを作る際、入力欄の中に薄い文字で「例:山田 太郎」と表示させるplaceholder属性は、ユーザーの入力を補助する要素です。

さらに、入力欄の幅や高さを適切に調整しないと、文字が途切れたり、タップしづらかったりします。

入力欄の幅は、ピクセル(px)で固定してはいけません。

CSSでwidth: 100%;を指定し、さらに box-sizing: border-box; をかけるのが実務のルールです。

これにより、画面サイズが変わっても枠内に収まる伸縮自在の入力欄になります。

❌ 悪い例(px固定・高さが狭い)

input {
  width: 350px; /* はみ出す原因 */
  /* paddingがないのでタップしにくい */
}
⭕️ 良い例(100%伸縮・タップしやすい高さ)
input {
  width: 100%; /* 画面に合わせて伸縮 */
  box-sizing: border-box; /* はみ出し防止の要 */
  padding: 12px; /* 高さを出してタップしやすく */
}
HTMLコード表示
<div class="hform-layout2-wrapper">
  
  <div class="hform-layout2-demo-area">
    
    <div class="hform-layout2-box">
      <div class="hform-layout2-label" style="color:#dc3545;">❌ 悪い例(px固定・高さが狭い)</div>
      
      <div class="hform-layout2-mobile-sim">
        <label style="font-size:12px; color:#666;">お名前</label><br>
        <input type="text" placeholder="例:山田太郎" class="hform-layout2-input-bad">
      </div>

      <div class="hform-layout2-code hform-layout2-code-bad">
        input {<br>
          <span class="hform-layout2-hl-red">width: 350px;</span> /* はみ出す原因 */<br>
          <span class="hform-layout2-hl-note">/* paddingがないのでタップしにくい */</span><br>
        }
      </div>
    </div>

    <div class="hform-layout2-box">
      <div class="hform-layout2-label" style="color:#198754;">⭕️ 良い例(100%伸縮・タップしやすい高さ)</div>
      
      <div class="hform-layout2-mobile-sim">
        <label style="font-size:12px; font-weight:bold; color:#333; margin-bottom:5px; display:block;">お名前</label>
        <input type="text" placeholder="例:山田太郎" class="hform-layout2-input-good">
      </div>

      <div class="hform-layout2-code hform-layout2-code-good">
        input {<br>
          <span class="hform-layout2-hl-green">width: 100%;</span> /* 画面に合わせて伸縮 */<br>
          <span class="hform-layout2-hl-green">box-sizing: border-box;</span> /* はみ出し防止の要 */<br>
          padding: 12px; /* 高さを出してタップしやすく */<br>
        }
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hform-layout2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-layout2-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hform-layout2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-layout2-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

/* スマホサイズのシミュレーション枠(わざと狭くする) */
.hform-layout2-mobile-sim {
  width: 250px; 
  background-color: #e9ecef;
  padding: 15px;
  border-radius: 4px;
  margin-bottom: 15px;
  border: 1px solid #ced4da;
  /* 突き破りを見せるためにoverflowは指定しない */
}

/* ❌ 悪い入力欄 */
.hform-layout2-input-bad {
  /* わざと親の幅(250px)より大きい固定値を指定 */
  width: 300px; 
  /* 高さの確保もしていないので狭い */
  border: 1px solid #ccc;
}

/* ⭕️ 良い入力欄 */
.hform-layout2-input-good {
  width: 100%; /* 親の幅(250px)にピッタリ合わせる */
  box-sizing: border-box; /* borderやpaddingを含めて100%にする */
  padding: 12px; /* タップしやすい高さを確保 */
  border: 1px solid #0d6efd;
  border-radius: 4px;
  font-size: 16px; /* スマホでのズームを防ぐために16px以上推奨 */
}
.hform-layout2-input-good::placeholder {
  color: #adb5bd; /* プレースホルダーの文字色を少し薄くする */
}

.hform-layout2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hform-layout2-code-bad { border-left: 4px solid #dc3545; }
.hform-layout2-code-good { border-left: 4px solid #198754; }
.hform-layout2-hl-red { color: #e06c75; font-weight: bold; }
.hform-layout2-hl-green { color: #98c379; font-weight: bold; }
.hform-layout2-hl-note { color: #5c6370; font-style: italic; }

widthheightの使い方やボックスモデルを理解したい人は「【html&css】width(横幅)とheight(高さ)の指定とボックスモデル」を一読ください。

入力チェックと必須項目の設定

お問い合わせや会員登録のフォームにおいて、ユーザーが何も入力せずに送信ボタンを押してしまったり、電話番号の欄にひらがなを入力してしまったりするのを防ぐ機能を「入力チェック」と呼びます。

正しいデータをサーバーに送ることは、システムのバグを防ぎ、ユーザーにエラーを知らせるUIを作る上で欠かせません。

ここでは、HTML5の便利な標準機能、実務で必須になるJavaScriptを使ったチェックを解説します。

入力チェックと必須項目の設定
  • HTML5の属性で必須や文字数制限をする
  • JavaScriptを使ったカスタムバリデーション

HTML5の属性で必須や文字数制限をする

HTML5では、複雑なプログラムを書かなくても<input>タグに属性を追加するだけで、ブラウザが自動的に入力チェックを行います。

  • 必須項目にする
    required属性をつけると、空欄のまま送信しようとした時にブラウザがストップをかけます。
  • 文字数を制限する
    minlength="8"(最低8文字)やmaxlength="20"(最大20文字)を指定できます。
  • 数値を制限する
    type="number"に対してmin="18"(18以上)などを指定できます。

必須というデザインラベルとタグへのrequired属性の付与は、セットで行うのがよいです。

🛡️ HTML5標準のバリデーション
<!– 1. 必須にする –>
<input type=”text” required>

<!– 2. 文字数を制限する –>
<input type=”password” minlength=”8″ maxlength=”12″>

※何も入力せずに送信ボタンを押すと、ブラウザ標準のポップアップで「このフィールドを入力してください」と警告が出ます。

HTMLコード表示
<div class="hform-val1-wrapper">
  
  <div class="hform-val1-demo-area">
    
    <div class="hform-val1-box">
      <div class="hform-val1-label">🛡️ HTML5標準のバリデーション</div>
      
      <div class="hform-val1-visual">
        <form onsubmit="event.preventDefault(); alert('全ての条件をクリアし、送信されました!');">
          
          <div class="hform-val1-group">
            <label>お名前 <span class="hform-val1-req">必須</span></label>
            <input type="text" required placeholder="入力してください" class="hform-val1-input">
          </div>

          <div class="hform-val1-group">
            <label>パスワード <span class="hform-val1-req">必須</span></label>
            <input type="password" required minlength="8" maxlength="12" placeholder="8〜12文字で入力" class="hform-val1-input">
          </div>

          <button type="submit" class="hform-val1-btn">送信チェック</button>
        </form>
      </div>

      <div class="hform-val1-code">
        <!-- 1. 必須にする --><br>
        <input type="text" <span class="hform-val1-hl-green">required</span>><br><br>
        <!-- 2. 文字数を制限する --><br>
        <input type="password" <span class="hform-val1-hl-green">minlength="8" maxlength="12"</span>>
      </div>
      <p class="hform-val1-note">※何も入力せずに送信ボタンを押すと、ブラウザ標準のポップアップで「このフィールドを入力してください」と警告が出ます。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-val1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-val1-demo-area {
  display: flex;
  justify-content: center;
}
.hform-val1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-val1-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #333; }

.hform-val1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hform-val1-group {
  margin-bottom: 15px;
}
.hform-val1-group label {
  display: block;
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 5px;
  color: #333;
}
.hform-val1-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}
.hform-val1-btn {
  width: 100%;
  padding: 12px;
  background-color: #0d6efd;
  color: white;
  border: none;
  border-radius: 4px;
  font-weight: bold;
  cursor: pointer;
}
.hform-val1-req {
  background-color: #dc3545;
  color: white;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 3px;
  margin-left: 5px;
}

.hform-val1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hform-val1-hl-green { color: #98c379; font-weight: bold; }
.hform-val1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

JavaScriptを使ったカスタムバリデーション

HTML5のrequiredは便利ですが、「ブラウザによって警告ポップアップのデザインが違う」「独自のメッセージが出せない」「入力欄の下に赤文字でリアルタイムにエラーを出したい」といった要望に応えられません。

実務レベルの案件では、JavaScriptを使って、独自のエラーメッセージを表示するカスタムバリデーションを実装するのが一般的です。

フォームの送信処理(onsubmitイベント)の中でエラーを検知した場合、送信処理を強制キャンセルする命令を書かなければなりません。

現在のJavaScriptではevent.preventDefault();を呼び出すことで、フォームのデフォルトの送信挙動をストップさせます。

⚡ JavaScriptによるカスタムバリデーション
// フォーム送信時のイベントを監視
form.addEventListener(‘submit’, function(event) {
  if (emailが空っぽなら) {
    /* 独自のエラーメッセージを表示 */
    errorArea.textContent = ‘メールアドレスは必須です’;

    /* ★超重要:エラー時は送信を強制ストップ! */
    event.preventDefault();
  }
});
HTMLコード表示
<div class="hform-val2-wrapper">
  
  <div class="hform-val2-demo-area">
    
    <div class="hform-val2-box">
      <div class="hform-val2-label">⚡ JavaScriptによるカスタムバリデーション</div>
      
      <div class="hform-val2-visual">
        <form id="hform-val2-myForm">
          
          <div class="hform-val2-group">
            <label>メールアドレス <span class="hform-val1-req">必須</span></label>
            <input type="text" id="hform-val2-email" placeholder="example@test.com" class="hform-val2-input">
            <div id="hform-val2-error-email" class="hform-val2-error-msg"></div>
          </div>

          <button type="submit" class="hform-val2-btn">送信する</button>
        </form>
      </div>

      <div class="hform-val2-code">
        // フォーム送信時のイベントを監視<br>
        form.addEventListener('submit', function(<span class="hform-val2-hl-blue">event</span>) {<br>
          if (emailが空っぽなら) {<br>
            /* 独自のエラーメッセージを表示 */<br>
            errorArea.textContent = 'メールアドレスは必須です';<br><br>
            <span class="hform-val2-hl-pink">/* ★超重要:エラー時は送信を強制ストップ! */</span><br>
            <span class="hform-val2-hl-pink">event.preventDefault();</span><br>
          }<br>
        });
      </div>
    </div>

  </div>
</div>
CSSコード表示
.hform-val2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-val2-demo-area {
  display: flex;
  justify-content: center;
}
.hform-val2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-val2-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #d63384; }

.hform-val2-visual {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}
.hform-val2-group {
  margin-bottom: 15px;
}
.hform-val2-group label {
  display: block;
  font-size: 13px;
  font-weight: bold;
  margin-bottom: 5px;
  color: #333;
}
.hform-val2-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
  font-size: 14px;
  transition: border-color 0.3s;
}
.hform-val2-input.error {
  border-color: #dc3545;
  background-color: #f8d7da;
}
/* カスタムエラーメッセージのデザイン */
.hform-val2-error-msg {
  color: #dc3545;
  font-size: 12px;
  margin-top: 5px;
  font-weight: bold;
  min-height: 18px; /* ガタつき防止 */
}

.hform-val2-btn {
  width: 100%;
  padding: 12px;
  background-color: #d63384;
  color: white;
  border: none;
  border-radius: 4px;
  font-weight: bold;
  cursor: pointer;
}
.hform-val1-req {
  background-color: #dc3545;
  color: white;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 3px;
  margin-left: 5px;
}

.hform-val2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #d63384;
}
.hform-val2-hl-blue { color: #61afef; font-weight: bold; }
.hform-val2-hl-pink { color: #c678dd; font-weight: bold; }
JavaScriptコード表示
// デモ用のカスタムバリデーション処理
document.getElementById('hform-val2-myForm').addEventListener('submit', function(event) {
  const emailInput = document.getElementById('hform-val2-email');
  const errorMsg = document.getElementById('hform-val2-error-email');
  
  // エラー状態のリセット
  emailInput.classList.remove('error');
  errorMsg.textContent = '';
  
  // バリデーションチェック
  if (emailInput.value.trim() === '') {
    // 1. エラーメッセージを表示
    errorMsg.textContent = '※メールアドレスを入力してください。';
    emailInput.classList.add('error');
    
    // 2. 送信をストップ(超重要)
    event.preventDefault();
  } else if (!emailInput.value.includes('@')) {
    errorMsg.textContent = '※正しいメールアドレスの形式(@を含む)で入力してください。';
    emailInput.classList.add('error');
    event.preventDefault();
  } else {
    // 成功時
    event.preventDefault(); // デモ画面遷移防止
    alert('バリデーション成功!データが送信されました。');
    emailInput.value = ''; // クリア
  }
});

// リアルタイムに入力中のエラーを消す親切設計
document.getElementById('hform-val2-email').addEventListener('input', function() {
  this.classList.remove('error');
  document.getElementById('hform-val2-error-email').textContent = '';
});

フォーム送信時の応用と注意点

お問い合わせフォームや入力画面の基本ができたら、ユーザーの誤操作を防ぐ工夫や複数処理を一つの画面で実現する応用的な設定が求められます。

ここでは、Enterキーの暴発問題やボタンが複数ある時の処理について解説します。

フォーム送信時の応用と注意点
  • 1つのformタグ内に複数の送信ボタンを置く方法
  • Enterキーでの誤送信を防ぐ方法
  • formの中にform(ネスト)はNG

1つのformタグ内に複数の送信ボタンを置く方法

1つのフォームの中に、「下書き保存」ボタンと「確認画面へ進む」ボタンのように、役割の違う2つの送信ボタンを置きたい場合があります。

現在のHTML5では、JavaScriptに頼る必要はありません。

送信ボタンに対してformaction属性を付与するだけで、「このボタンを押した時だけ違うURLに送信する」という指定ができます。

🔀 1つのフォームから2箇所へ送信
<form action=”/send” method=”POST”>
  …
  <!– 1. 普通のボタン –>
  <button type=”submit”>本送信</button>

  <!– 2. 送信先を上書きするボタン –>
  <button type=”submit” formaction=”/save-draft”>
    下書き保存
  </button>
</form>

※JavaScriptを使わず、HTMLの属性だけで送信先(アクション)を分岐できるため、バグが起きにくく非常に安全です。

HTMLコード表示
<div class="hform-adv1-wrapper">
  
  <div class="hform-adv1-demo-area">
    
    <div class="hform-adv1-box">
      <div class="hform-adv1-label">🔀 1つのフォームから2箇所へ送信</div>
      
      <div class="hform-adv1-visual">
        <form action="/send" method="POST" onsubmit="event.preventDefault(); alert('「/send(本送信)」へ送りました!');">
          <div style="margin-bottom: 15px;">
            <label style="display:block; font-size:12px; font-weight:bold; color:#666; margin-bottom:5px;">記事のタイトル</label>
            <input type="text" placeholder="タイトルを入力" class="hform-adv1-input">
          </div>
          
          <div class="hform-adv1-btn-group">
            <button type="submit" class="hform-adv1-btn hform-adv1-btn-main">本送信する</button>
            
            <button type="submit" formaction="/save-draft" onclick="event.preventDefault(); alert('「/save-draft(下書き)」へ送りました!');" class="hform-adv1-btn hform-adv1-btn-sub">下書き保存</button>
          </div>
        </form>
      </div>

      <div class="hform-adv1-code">
        <form <span class="hform-adv1-hl-blue">action="/send"</span> method="POST"><br>
          ...<br>
          <!-- 1. 普通のボタン --><br>
          <button type="submit">本送信</button><br><br>
          <!-- 2. 送信先を上書きするボタン --><br>
          <button type="submit" <span class="hform-adv1-hl-pink">formaction="/save-draft"</span>><br>
            下書き保存<br>
          </button><br>
        </form>
      </div>
      <p class="hform-adv1-note">※JavaScriptを使わず、HTMLの属性だけで送信先(アクション)を分岐できるため、バグが起きにくく非常に安全です。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-adv1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-adv1-demo-area {
  display: flex;
  justify-content: center;
}
.hform-adv1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-adv1-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #0d6efd; }

.hform-adv1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hform-adv1-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}

/* ボタンを横並びにする */
.hform-adv1-btn-group {
  display: flex;
  gap: 10px;
}
.hform-adv1-btn {
  flex: 1; /* 幅を均等にする */
  padding: 12px;
  border: none;
  border-radius: 4px;
  font-weight: bold;
  cursor: pointer;
}
.hform-adv1-btn-main {
  background-color: #0d6efd;
  color: white;
}
.hform-adv1-btn-sub {
  background-color: #6c757d;
  color: white;
}

.hform-adv1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hform-adv1-hl-blue { color: #61afef; font-weight: bold; }
.hform-adv1-hl-pink { color: #c678dd; font-weight: bold; }
.hform-adv1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

Enterキーでの誤送信を防ぐ方法

Webブラウザの標準仕様として、フォーム内の入力欄にカーソルがある状態で「Enterキー」を押すと、自動的にフォームが送信されるという機能があります。

実務レベルのフォームでは、JavaScriptを使ってEnterキーによる誤送信を無効化するのが親切なUI設計です。

具体的には、入力欄でキーボードが押されたイベント(keydown)を監視し、Enterキーだった場合は「何もしない(無効化する)」という処理を仕込みます。

ただし<textarea>内のEnterは純粋な改行として必要なので無効化から除外します。

🚫 Enterキーの誤送信防止
<!– inputタグに1行追記するだけの最も簡単な方法 –>
<input type=”text” onkeydown=”if(event.key === ‘Enter’) event.preventDefault();”>

<!– ※textareaは改行のためにEnterが必要なので設定しません –>

※実務では、すべてのinputタグにいちいち書くのは大変なので、JavaScript側で querySelectorAll('input') を使って一括で無効化処理をかけるのが一般的です。

HTMLコード表示
<div class="hform-adv2-wrapper">
  
  <div class="hform-adv2-demo-area">
    
    <div class="hform-adv2-box">
      <div class="hform-adv2-label">🚫 Enterキーの誤送信防止</div>
      
      <div class="hform-adv2-visual">
        <form onsubmit="event.preventDefault(); alert('送信ボタンが押されました!');">
          <div style="margin-bottom: 15px;">
            <label style="display:block; font-size:12px; font-weight:bold; color:#666; margin-bottom:5px;">試しに入力してEnterキーを押してください</label>
            
            <input type="text" placeholder="Enterを押しても送信されません" class="hform-adv2-input" onkeydown="if(event.key === 'Enter') event.preventDefault();">
          </div>
          
          <button type="submit" class="hform-adv2-btn">正規の送信ボタン</button>
        </form>
      </div>

      <div class="hform-adv2-code">
        <!-- inputタグに1行追記するだけの最も簡単な方法 --><br>
        <input type="text" <span class="hform-adv2-hl-green">onkeydown="if(event.key === 'Enter') event.preventDefault();"</span>><br><br>
        <!-- ※textareaは改行のためにEnterが必要なので設定しません -->
      </div>
      <p class="hform-adv2-note">※実務では、すべてのinputタグにいちいち書くのは大変なので、JavaScript側で <code>querySelectorAll('input')</code> を使って一括で無効化処理をかけるのが一般的です。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-adv2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-adv2-demo-area {
  display: flex;
  justify-content: center;
}
.hform-adv2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-adv2-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #198754; }

.hform-adv2-visual {
  background-color: #d1e7dd;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #badbcc;
}
.hform-adv2-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}
.hform-adv2-btn {
  width: 100%;
  padding: 12px;
  background-color: #198754;
  color: white;
  border: none;
  border-radius: 4px;
  font-weight: bold;
  cursor: pointer;
}

.hform-adv2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hform-adv2-hl-green { color: #98c379; font-weight: bold; }
.hform-adv2-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

formの中にform(ネスト)はNG

Webサイトを作っていると、「ページ全体を覆う会員登録フォーム(親)」の中に、デザインの都合上「郵便番号から住所を自動入力する小さな検索フォーム(子)」を置きたいなどの状況が発生することがあります。

HTMLの仕様において、「formの中にformを入れる(ネスト)こと」は禁止されています。

これをやると、ブラウザがどちらのフォームを送信すればいいか分からなくなり、意図しないデータが送られたり、ボタンが効かなくなったりする致命的なバグを引き起こします。

これを回避して「独立した2つのフォーム」をデザイン上は入れ子のように見せたい場合は、form属性を使います。

❌ 絶対NG(formの入れ子)
<form action=”/main”> <!– 親フォーム –>
  お名前:<input type=”text”>

  <!– ⚠️ 検索用に別のformを入れてしまう(文法違反!) –>
  <form action=”/search”>
    郵便番号:<input type=”text”>
    <button type=”submit”>検索</button>
  </form>

  <button type=”submit”>本送信</button>
</form>

※これをやると、検索ボタンを押したのに本送信されてしまうなど、深刻なバグが発生します。

⭕️ 回避策(form属性で紐付け)
<!– 1. 検索用フォームを完全に外(独立)に出す –>
<form action=”/search” id=”subForm”>
</form>

<!– 2. メインフォーム –>
<form action=”/main”>
  お名前:<input type=”text”>

  <!– 3. 検索ボタンだけをメイン内に置き、idで紐付ける –>
  郵便番号:<input type=”text” form=”subForm”>
  <button type=”submit” form=”subForm”>検索</button>

  <button type=”submit”>本送信</button>
</form>

form="対象のID" と指定するだけで、物理的に離れたformタグにデータを送ることができます。これで入れ子を完全に回避できます。

HTMLコード表示
<div class="hform-adv3-wrapper">
  
  <div class="hform-adv3-demo-area">
    
    <div class="hform-adv3-box">
      <div class="hform-adv3-label" style="color:#dc3545;">❌ 絶対NG(formの入れ子)</div>
      
      <div class="hform-adv3-code hform-adv3-code-bad">
        <span class="hform-adv3-hl-red"><form action="/main"></span> <!-- 親フォーム --><br>
          お名前:<input type="text"><br><br>
          <!-- ⚠️ 検索用に別のformを入れてしまう(文法違反!) --><br>
          <span class="hform-adv3-hl-red"><form action="/search"></span><br>
            郵便番号:<input type="text"><br>
            <button type="submit">検索</button><br>
          <span class="hform-adv3-hl-red"></form></span><br><br>
          <button type="submit">本送信</button><br>
        <span class="hform-adv3-hl-red"></form></span>
      </div>
      <p class="hform-adv3-note">※これをやると、検索ボタンを押したのに本送信されてしまうなど、深刻なバグが発生します。</p>
    </div>

    <div class="hform-adv3-box">
      <div class="hform-adv3-label" style="color:#198754;">⭕️ 回避策(form属性で紐付け)</div>
      
      <div class="hform-adv3-code hform-adv3-code-good">
        <!-- 1. 検索用フォームを完全に外(独立)に出す --><br>
        <form action="/search" <span class="hform-adv3-hl-green">id="subForm"</span>><br>
        </form><br><br>
        <!-- 2. メインフォーム --><br>
        <form action="/main"><br>
          お名前:<input type="text"><br><br>
          <!-- 3. 検索ボタンだけをメイン内に置き、idで紐付ける --><br>
          郵便番号:<input type="text" <span class="hform-adv3-hl-green">form="subForm"</span>><br>
          <button type="submit" <span class="hform-adv3-hl-green">form="subForm"</span>>検索</button><br><br>
          <button type="submit">本送信</button><br>
        </form>
      </div>
      <p class="hform-adv3-note" style="color:#198754;">※ <code>form="対象のID"</code> と指定するだけで、物理的に離れたformタグにデータを送ることができます。これで入れ子を完全に回避できます。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-adv3-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-adv3-demo-area {
  display: flex;
  flex-direction: column;
  gap: 30px;
  align-items: center;
}
.hform-adv3-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 20px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hform-adv3-label { font-size: 14px; font-weight: bold; margin-bottom: 15px; }

.hform-adv3-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
}
.hform-adv3-code-bad { border-left: 4px solid #dc3545; }
.hform-adv3-code-good { border-left: 4px solid #198754; }
.hform-adv3-hl-red { color: #e06c75; font-weight: bold; }
.hform-adv3-hl-green { color: #98c379; font-weight: bold; }
.hform-adv3-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

JavaScriptやPHPとの連携

HTMLで作成したフォームの目的は、入力されたデータを裏側のシステムへ送り届けることです。

Web開発におけるフォームのデータ受け渡しは、ページ遷移を伴うHTML標準の送信方法だけでなく、JavaScriptを使った非同期送信やPHPなどのサーバー側との連携が必須になります。

ここでは、JavaScriptによるデータ送信手法とPHP開発の「入力値の消失問題」の解決策を解説します。

JavaScriptやPHPとの連携
  • JavaScriptでフォームの値を取得・JSONで送信する
  • PHPでデータを受け取る・入力値を保持する

JavaScriptでフォームの値を取得・JSONで送信する

Webアプリでは、HTMLの機能で直接送信するのではなく、JavaScript側でフォームの値を取得し、JSON形式に変換して裏側に送信するという手法が主流です。

実務では、個別に値を取得しません。

new FormData(form要素)という機能を使えば、フォームの中にある全てのデータを「キーと値のセット」として回収してくれます。

そして、サーバーへ送信する際はfetchなどを用い、ヘッダーにContent-Type: application/jsonを指定してJSONデータを送るのがスタンダードです。

🚀 JSでの一括取得とJSON化
// 1. form要素を取得
const form = document.getElementById(‘myForm’);

form.addEventListener(‘submit’, (e) => {
  e.preventDefault(); // デフォルトの送信をストップ

  // 2. FormDataで全項目を一瞬で回収!
  const formData = new FormData(form);

  // 3. オブジェクトに変換し、JSON文字列にする
  const jsonData = JSON.stringify(Object.fromEntries(formData));

  /* このjsonDataを fetch API 等で送信する */
});

※送信ボタンを押すと、上のフォームの内容が一瞬でJSONデータに変換されて画面に表示されます。

HTMLコード表示
<div class="hform-back1-wrapper">
  
  <div class="hform-back1-demo-area">
    
    <div class="hform-back1-box">
      <div class="hform-back1-label">🚀 JSでの一括取得とJSON化</div>
      
      <div class="hform-back1-visual">
        <form id="hform-back1-form">
          <div style="margin-bottom: 10px;">
            <input type="text" name="username" placeholder="お名前" class="hform-back1-input">
          </div>
          <div style="margin-bottom: 15px;">
            <input type="email" name="user_email" placeholder="メールアドレス" class="hform-back1-input">
          </div>
          <button type="submit" class="hform-back1-btn">JSONで送信する</button>
        </form>
        
        <div id="hform-back1-result" class="hform-back1-result-area" style="display:none;"></div>
      </div>

      <div class="hform-back1-code">
        // 1. form要素を取得<br>
        const form = document.getElementById('myForm');<br><br>
        form.addEventListener('submit', (e) => {<br>
          e.preventDefault(); // デフォルトの送信をストップ<br><br>
          <span class="hform-back1-hl-green">// 2. FormDataで全項目を一瞬で回収!</span><br>
          const formData = <span class="hform-back1-hl-blue">new FormData(form)</span>;<br><br>
          <span class="hform-back1-hl-green">// 3. オブジェクトに変換し、JSON文字列にする</span><br>
          const jsonData = JSON.stringify(<span class="hform-back1-hl-blue">Object.fromEntries(formData)</span>);<br><br>
          /* このjsonDataを fetch API 等で送信する */<br>
        });
      </div>
      <p class="hform-back1-note">※送信ボタンを押すと、上のフォームの内容が一瞬でJSONデータに変換されて画面に表示されます。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-back1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-back1-demo-area {
  display: flex;
  justify-content: center;
}
.hform-back1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 450px;
  border-radius: 4px;
}
.hform-back1-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #333; }

.hform-back1-visual {
  background-color: #f1f3f5;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
}
.hform-back1-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
}
.hform-back1-btn {
  width: 100%;
  padding: 12px;
  background-color: #0d6efd;
  color: white;
  border: none;
  border-radius: 4px;
  font-weight: bold;
  cursor: pointer;
}
.hform-back1-result-area {
  margin-top: 15px;
  padding: 10px;
  background-color: #282c34;
  color: #98c379;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  word-break: break-all;
}

.hform-back1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hform-back1-hl-blue { color: #61afef; font-weight: bold; }
.hform-back1-hl-green { color: #98c379; }
.hform-back1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }
JavaScriptコード表示
document.getElementById('hform-back1-form').addEventListener('submit', function(e) {
  e.preventDefault(); // 画面遷移を防ぐ
  
  // FormDataで一括取得
  const formData = new FormData(this);
  // オブジェクト化してJSON文字列にする
  const jsonData = JSON.stringify(Object.fromEntries(formData), null, 2);
  
  // 結果を表示
  const resultArea = document.getElementById('hform-back1-result');
  resultArea.style.display = 'block';
  resultArea.textContent = jsonData;
});

PHPでデータを受け取る・入力値を保持する

お問い合わせフォームなどをPHPで作成する際、HTMLから送られてきたデータは$_POST$_GETという変数の中に格納されます。

PHPでフォームを作る際は、入力画面と確認画面を行き来してもデータが消えないように、<input>タグのvalue属性の中に、「先ほど送信されたデータ($_POST)があれば、もう一度出力する」というコードを仕込みます。

この時、悪意のあるプログラムが実行されないよう、htmlspecialchars()という関数を使って無害化することがセキュリティ上の条件です。

🐘 PHPでの安全な入力値保持(復元)
⚠ 氏名が未入力です。(エラーで戻ってきた状態を想定)
↑ 消えずに残っている親切な設計
<!– HTML内にPHPを組み込んで value に値を入れる –>
<input type=”email” name=”email”
  value=”<?php
    // 送信された$_POST[‘email’]が存在すれば表示する
    echo htmlspecialchars(
      $_POST[‘email’] ?? ”,
      ENT_QUOTES, ‘UTF-8’
    );
  ?>“>

htmlspecialchars は、悪意のあるタグ入力を防ぐための必須のセキュリティ対策です。これを怠るとサイトが乗っ取られる危険があります。

HTMLコード表示
<div class="hform-back2-wrapper">
  
  <div class="hform-back2-demo-area">
    
    <div class="hform-back2-box">
      <div class="hform-back2-label">🐘 PHPでの安全な入力値保持(復元)</div>
      
      <div class="hform-back2-visual">
        <div style="color:#dc3545; font-size:12px; font-weight:bold; margin-bottom:10px;">
          ⚠ 氏名が未入力です。(エラーで戻ってきた状態を想定)
        </div>
        
        <div style="margin-bottom:10px;">
          <label style="font-size:12px; font-weight:bold; color:#666;">氏名</label>
          <input type="text" value="" class="hform-back2-input" style="border-color:#dc3545;">
        </div>

        <div style="margin-bottom:15px;">
          <label style="font-size:12px; font-weight:bold; color:#666;">メールアドレス</label>
          <input type="email" value="user@example.com" class="hform-back2-input" readonly>
          <div style="font-size:11px; color:#198754; margin-top:3px;">↑ 消えずに残っている親切な設計</div>
        </div>
      </div>

      <div class="hform-back2-code">
        <!-- HTML内にPHPを組み込んで value に値を入れる --><br>
        <input type="email" name="email" <br>
          value="<span class="hform-back2-hl-pink"><?php</span><br>
            // 送信された$_POST['email']が存在すれば表示する<br>
            echo <span class="hform-back2-hl-yellow">htmlspecialchars</span>(<br>
              $_POST['email'] ?? '', <br>
              ENT_QUOTES, 'UTF-8'<br>
            ); <br>
          <span class="hform-back2-hl-pink">?></span>">
      </div>
      <p class="hform-back2-note">※ <code>htmlspecialchars</code> は、悪意のあるタグ入力を防ぐための必須のセキュリティ対策です。これを怠るとサイトが乗っ取られる危険があります。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-back2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-back2-demo-area {
  display: flex;
  justify-content: center;
}
.hform-back2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 480px;
  border-radius: 4px;
}
.hform-back2-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #4F5B93; } /* PHPカラー */

.hform-back2-visual {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #dee2e6;
  box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}
.hform-back2-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-sizing: border-box;
  background-color: #f8f9fa;
}

.hform-back2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #4F5B93;
}
.hform-back2-hl-pink { color: #c678dd; font-weight: bold; }
.hform-back2-hl-yellow { color: #e5c07b; font-weight: bold; }
.hform-back2-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

外部ツールの埋め込みとWordPress連携

フォームをHTMLから自作し、PHPなどのバックエンドで処理するには、セキュリティ対策やメール送信機能の構築など、専門的な知識と工数が必要です。

実際のWeb制作の現場では、全てをゼロから自作するのではなく、WordPressのプラグインや外部のフォーム作成ツールを利用し、HTML/CSSで自サイトに馴染ませるという手法が使われます。

ここでは、代表的な2つのツールのカスタマイズ方法について解説します。

外部ツールの埋め込みとWordPress連携
  • Contact Form 7のHTMLカスタマイズ
  • GoogleフォームをHTMLサイトに埋め込む方法

Contact Form 7のHTMLカスタマイズ

WordPressでWebサイトを構築している場合、お問い合わせフォームの実装には「Contact Form 7」というプラグインがよく使われます。

このプラグインの特徴は、管理画面のエディタ内にHTMLタグと独自のショートコード([text* your-name]など)を混ぜてテンプレートを作れる点にあります。

Contact Form 7のコードを書くときは、<form>タグは書かず、<div><label>でレイアウトを作り、入力欄を出したい場所にショートコードを置くのがよいです。

クラスを付与してCSSでデザインを整えます。

⚙️ Contact Form 7のカスタマイズ
<!– 📝 WPの管理画面(CF7のエディタ)に書くコード –>
<!– ❌ ここに <form> は絶対に書かない! –>

<div class=”cf7-group”>
  <label>お名前 必須</label>
  <!– inputタグの代わりにショートコードを書く –>
  [text* your-name class:cf7-input placeholder “山田 太郎”]
</div>

<div class=”cf7-submit-area”>
  [submit class:cf7-btn “送信する”]
</div>
⬇️ 自動変換 ⬇️
<!– 🌐 実際のブラウザに出力されるHTML –>
<form action=”/contact#wpcf7-f1-p2-o1″ method=”post” …>
  <div class=”cf7-group”>
    <label>お名前 <span>必須</span></label>
    <!– ショートコードがinputタグに化ける! –>
    <input type=”text” name=”your-name” class=”cf7-input” placeholder=”山田 太郎” required>
  </div>
  <div class=”cf7-submit-area”>
    <input type=”submit” value=”送信する” class=”cf7-btn”>
  </div>
</form>

※出力された cf7-input などのクラスに対して、自分のCSSファイルでスタイルを当てておしゃれに装飾(デザイン)します。

HTMLコード表示
<div class="hform-ext1-wrapper">
  
  <div class="hform-ext1-demo-area">
    
    <div class="hform-ext1-box">
      <div class="hform-ext1-label">⚙️ Contact Form 7のカスタマイズ</div>
      
      <div class="hform-ext1-code">
        <!-- 📝 WPの管理画面(CF7のエディタ)に書くコード --><br>
        <!-- ❌ ここに <form> は絶対に書かない! --><br><br>
        <div class="cf7-group"><br>
          <label>お名前 <span class="hform-ext1-hl-req">必須</span></label><br>
          <!-- inputタグの代わりにショートコードを書く --><br>
          <span class="hform-ext1-hl-blue">[text* your-name class:cf7-input placeholder "山田 太郎"]</span><br>
        </div><br><br>
        <div class="cf7-submit-area"><br>
          <span class="hform-ext1-hl-blue">[submit class:cf7-btn "送信する"]</span><br>
        </div>
      </div>

      <div style="text-align:center; color:#0d6efd; font-size:24px; margin: 10px 0;">⬇️ 自動変換 ⬇️</div>

      <div class="hform-ext1-code" style="border-left-color: #198754;">
        <!-- 🌐 実際のブラウザに出力されるHTML --><br>
        <span class="hform-ext1-hl-green"><form action="/contact#wpcf7-f1-p2-o1" method="post" ...></span><br>
          <div class="cf7-group"><br>
            <label>お名前 <span>必須</span></label><br>
            <!-- ショートコードがinputタグに化ける! --><br>
            <span class="hform-ext1-hl-green"><input type="text" name="your-name" class="cf7-input" placeholder="山田 太郎" required></span><br>
          </div><br>
          <div class="cf7-submit-area"><br>
            <span class="hform-ext1-hl-green"><input type="submit" value="送信する" class="cf7-btn"></span><br>
          </div><br>
        <span class="hform-ext1-hl-green"></form></span>
      </div>
      <p class="hform-ext1-note">※出力された <code>cf7-input</code> などのクラスに対して、自分のCSSファイルでスタイルを当てておしゃれに装飾(デザイン)します。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-ext1-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-ext1-demo-area {
  display: flex;
  justify-content: center;
}
.hform-ext1-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hform-ext1-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #333; }

.hform-ext1-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #0d6efd;
}
.hform-ext1-hl-blue { color: #61afef; font-weight: bold; }
.hform-ext1-hl-green { color: #98c379; font-weight: bold; }
.hform-ext1-hl-req { color: #e06c75; font-size: 11px; border: 1px solid #e06c75; padding: 1px 4px; border-radius: 2px; }
.hform-ext1-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

GoogleフォームをHTMLサイトに埋め込む方法

システム開発費をかけずにお問い合わせ機能を作る方法が、Googleフォームを自社のHTMLサイトに埋め込むやり方です。

iframeで埋め込む際は、親のHTML側でmax-widthwidth: 100%を設定してレスポンシブ対応させます。

どうしてもGoogleフォームのデザインを自サイトのものにしたい場合、Googleフォームの送信先URLや項目のname属性(entry.1234567など)を解析し、HTMLフォームからGoogle側に送信するハックが存在します。

しかし、これはGoogleが仕様を少しでも変更するとデータが届かなくなるという高いリスクがあるため、実務の企業サイト等では絶対に非推奨です。

📝 Googleフォームの安全な埋め込み
↓スマホでの見え方イメージ↓
画面幅にぴったり収まった
Googleフォーム(width: 100%)
<!– ❌ Googleからコピーした直後(スマホではみ出す) –>
<iframe src=”https://docs.google.com/…” width=”640″ height=”800″></iframe>

<!– ⭕️ 実務での正しい修正方法 –>
<div class=”gform-wrap”>
  <iframe src=”https://docs.google.com/…” width=”100%” height=”800″ frameborder=”0″ marginheight=”0″ marginwidth=”0″>読み込み中…</iframe>
</div>

/* CSSで親要素に最大幅を持たせる */
.gform-wrap {
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
}

※iframe内のデザインは変更できないと割り切り、色やヘッダー画像はGoogleフォームの管理画面側の設定で可能な限り自サイトのトーンに合わせるのが正解です。

HTMLコード表示
<div class="hform-ext2-wrapper">
  
  <div class="hform-ext2-demo-area">
    
    <div class="hform-ext2-box">
      <div class="hform-ext2-label">📝 Googleフォームの安全な埋め込み</div>
      
      <div class="hform-ext2-visual" style="max-width: 300px; margin: 0 auto 20px;">
        <div style="font-size:12px; color:#666; margin-bottom:5px;">↓スマホでの見え方イメージ↓</div>
        <div style="background-color:#e2e3e5; padding:20px; text-align:center; border-radius:4px; border:2px dashed #adb5bd; color:#6c757d; font-size:13px;">
          画面幅にぴったり収まった<br>Googleフォーム(width: 100%)
        </div>
      </div>

      <div class="hform-ext2-code">
        <!-- ❌ Googleからコピーした直後(スマホではみ出す) --><br>
        <iframe src="https://docs.google.com/..." <span class="hform-ext2-hl-red">width="640"</span> height="800"></iframe><br><br>
        <!-- ⭕️ 実務での正しい修正方法 --><br>
        <div class="gform-wrap"><br>
          <iframe src="https://docs.google.com/..." <span class="hform-ext2-hl-green">width="100%"</span> height="800" frameborder="0" marginheight="0" marginwidth="0">読み込み中…</iframe><br>
        </div><br><br>
        /* CSSで親要素に最大幅を持たせる */<br>
        .gform-wrap {<br>
          width: 100%;<br>
          max-width: 640px;<br>
          margin: 0 auto;<br>
        }
      </div>
      <p class="hform-ext2-note">※iframe内のデザインは変更できないと割り切り、色やヘッダー画像はGoogleフォームの管理画面側の設定で可能な限り自サイトのトーンに合わせるのが正解です。</p>
    </div>

  </div>
</div>
CSSコード表示
.hform-ext2-wrapper {
  background-color: #f8f9fa;
  padding: 20px;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  font-family: sans-serif;
}
.hform-ext2-demo-area {
  display: flex;
  justify-content: center;
}
.hform-ext2-box {
  background-color: #ffffff;
  border: 2px dashed #adb5bd;
  padding: 25px;
  width: 100%;
  max-width: 500px;
  border-radius: 4px;
}
.hform-ext2-label { font-size: 15px; font-weight: bold; margin-bottom: 20px; color: #198754; }

.hform-ext2-code {
  background-color: #282c34;
  color: #abb2bf;
  padding: 15px;
  font-family: monospace;
  font-size: 13px;
  border-radius: 4px;
  line-height: 1.6;
  border-left: 4px solid #198754;
}
.hform-ext2-hl-red { color: #e06c75; font-weight: bold; }
.hform-ext2-hl-green { color: #98c379; font-weight: bold; }
.hform-ext2-note { font-size: 12px; color: #666; margin-top: 10px; line-height: 1.5; }

まとめ

分かりやすいようにまとめを記載します。

本記事のまとめ
  • 基本の役割
    入力部品を囲み、ユーザーのデータをサーバーへ送信する箱。
  • 必須の属性
    送信先URLを指定するactionと送信方式を指定するmethodの2つを記述する。
  • GETとPOST
    検索などURLに残したい場合はGET、個人情報やパスワードなど隠して送る場合はPOSTを使用する。
  • ファイルの送信
    画像などを送信する場合は、method="POST"enctype="multipart/form-data"をセットで指定する。
  • ラベルの紐付け
    <label>for属性と<input>id属性を一致させ、文字をタップしても選択できるようにする。
  • レイアウト(横並び)
    テーブルやfloatは使わず、親要素にdisplay: flex;を指定して横並びにし、スマホ時は縦並びにする。
  • サイズの最適化
    はみ出しを防ぐため、入力欄の幅はpxで固定せずwidth: 100%;box-sizing: border-box;を指定する。
  • 入力チェック(基本)
    HTML5のrequired(必須)やmaxlength(文字数制限)などの属性を活用する。
  • 入力チェック(応用)
    JSで独自のエラーを出す場合、エラー検知時にevent.preventDefault();を実行して送信をストップさせる。
  • 複数ボタンの配置
    1つのフォーム内で送信先を分けたい場合は、ボタンにformaction属性を指定する。
  • 誤送信の防止
    入力途中のEnterキーによる意図しない送信を防ぐため、JSでEnterキーのイベントを無効化する。
  • 絶対のNG行動
    <form>タグの中に別の<form>タグを配置する「入れ子(ネスト)」は文法違反であり厳禁。
  • JSでのデータ取得
    個別取得ではなくnew FormData()を使って一括取得し、JSONに変換して送信するのが主流。
  • PHPでのデータ保持
    画面遷移時にデータが消えないよう、value属性に$_POSTの値をhtmlspecialchars()でエスケープして出力する。
  • 外部ツールの利用
    Contact Form 7では<form>タグを自書きしない。
    Googleフォームのiframewidth="100%"に修正して埋め込む。

よくある質問(FAQ)

HTMLでフォームを作る基本的なタグは何ですか?

まず、全体を<form>タグで囲むのがルールです。

その箱の中に、1行のテキストやラジオボタンを作る<input>タグ、長文を入力する<textarea>タグ、プルダウンメニューを作る<select>タグなどを配置していきます。

最後に、データを送る<button type="submit">送信</button>を配置するのが基本の形です。

formタグのmethod=”GET”と”POST”の違いは何ですか?

データを送る「運び方」の違いです。

GETは、データがURLの末尾にくっついて丸見えの状態で送られます。

POSTは、データを裏側に隠して送るためURLには表示されません。

個人情報、パスワード、長文のお問い合わせ内容などを送る場合は、セキュリティの観点からPOSTを使用する必要があります。

HTMLフォームに入力された内容を「自分のメール宛」に送信するには?

初心者がつまずくポイントですが、実は「HTMLだけ」ではメールを送信することはできません。

HTMLは「画面の見た目」を作るだけの言語です。

入力されたデータをメールとして発信するには、PHPやRubyといった「サーバー側のプログラム」を書いて連携させる必要があります。

プログラミングが難しい場合は、「Googleフォーム」を埋め込んだり、WordPressのプラグインを利用するのが一般的です。

フォームの送信ボタンを押しても何も起きません。

よくある原因は以下の3つです。

  1. 入力部品やボタンが<form>タグで囲まれていない。
  2. 送信ボタンの属性が<button type="button">になっている。
  3. <form>タグのaction属性が正しく指定されていない、または空になっている。
入力項目を「必須」にするには?

必須にしたい<input><textarea>タグの中に、requiredという属性を書き足すだけです。

これだけで、ユーザーが空欄のまま送信ボタンを押した際に、ブラウザが「このフィールドを入力してください」といった警告を出して送信をストップします。

この記事を書いた人

sugiのアバター sugi Site operator

【経歴】玉川大学工学部卒業→新卒SIer企業入社→2年半後に独立→プログラミングスクール運営/受託案件→フリーランスエンジニア&SEOコンサル→Python特化のコンテンツサイトJob Code&UIコピペサイトCode Stock運営中

目次