HTMLフォーム入門
入力要素とバリデーションの基本
HTMLフォームの基本構造、さまざまなinput要素の種類、HTML5バリデーション属性まで、ユーザー入力を受け取るためのフォームの作り方を解説します。
こんな人向けの記事です
- HTMLフォームの作り方を基礎から学びたい
- input要素の種類と使い分けを知りたい
- HTML5バリデーションの使い方を理解したい
- フォームのアクセシビリティを意識した実装を学びたい
Step 1フォームの基本構造
HTMLフォームは、ユーザーからの入力を受け取るための仕組みです。ログイン画面、お問い合わせフォーム、検索ボックスなど、Webサイトのあらゆる場所で使われています。
フォームは <form> タグで囲み、その中に <label> と <input> を配置するのが基本です。
<form>
<label for="username">ユーザー名:</label>
<input type="text" id="username" name="username">
<br><br>
<label for="email">メールアドレス:</label>
<input type="email" id="email" name="email">
<br><br>
<button type="submit">送信</button>
</form>
フォームの基本要素は以下の通りです:
<form>— フォーム全体を囲むタグ。action属性で送信先URL、method属性で送信方法を指定する<label>— 入力欄の説明ラベル。for属性で対応するinputのidを指定する<input>— 入力欄。type属性で入力の種類を、name属性で送信時のキー名を指定する<button type="submit">— フォームの送信ボタン。クリックするとフォームのデータが送信される
<label for="username"> と <input id="username"> の for と id を一致させることで、ラベルをクリックしたときに入力欄にフォーカスが移ります。アクセシビリティの観点からも必ず設定しましょう。
Step 2input要素の種類
<input> タグは type 属性を変えることで、さまざまな入力形式に対応できます。ブラウザが入力形式に応じた専用のUIを表示してくれるため、適切な type を選ぶことが重要です。
<label for="t1">テキスト:</label>
<input type="text" id="t1" placeholder="名前を入力">
<label for="t2">メール:</label>
<input type="email" id="t2" placeholder="example@mail.com">
<label for="t3">パスワード:</label>
<input type="password" id="t3" placeholder="パスワード">
<label for="t4">数値:</label>
<input type="number" id="t4" min="0" max="100">
<label for="t5">日付:</label>
<input type="date" id="t5">
<label for="t6">範囲:</label>
<input type="range" id="t6" min="0" max="100">
<label for="t7">色:</label>
<input type="color" id="t7">
<label for="t8">ファイル:</label>
<input type="file" id="t8">
主な type 属性の一覧です:
| type | 用途 | 特徴 |
|---|---|---|
text | テキスト入力 | 一般的な1行テキスト |
email | メールアドレス | メール形式のバリデーション付き |
password | パスワード | 入力文字が非表示になる |
number | 数値 | 数値のみ入力可能、上下ボタン付き |
tel | 電話番号 | スマホではテンキーが表示される |
url | URL | URL形式のバリデーション付き |
search | 検索 | クリアボタンが付く場合がある |
date | 日付 | カレンダーピッカーが表示される |
time | 時刻 | 時刻選択UIが表示される |
datetime-local | 日時 | 日付と時刻を同時に選択 |
range | 範囲 | スライダーで値を選択 |
color | 色 | カラーピッカーが表示される |
file | ファイル選択 | ファイルアップロード用 |
hidden | 非表示 | 画面に表示されず値のみ送信 |
type を正しく選ぶと、スマートフォンで最適なキーボードが表示されます。例えば type="email" なら「@」キー付きのキーボード、type="tel" ならテンキーが表示されます。ユーザーの入力体験を向上させるために、目的に合った type を選びましょう。
電話番号や郵便番号のように「数字だけど計算に使わない値」には type="number" ではなく type="tel" や type="text" + inputmode="numeric" を使いましょう。type="number" は上下ボタンが付き、先頭のゼロが消えてしまうため不向きです。
Step 3select・textarea・チェックボックス・ラジオボタン
<input> 以外にも、フォームで使える入力要素があります。それぞれ用途が異なるため、場面に応じて使い分けましょう。
セレクトボックス(ドロップダウン)
選択肢の中から1つ(または複数)を選ぶときに使います。選択肢が多い場合はテキスト入力よりもユーザーにとって楽です。
<label for="s1">都道府県:</label>
<select id="s1" name="prefecture">
<option value="">選択してください</option>
<optgroup label="関東">
<option value="tokyo">東京都</option>
<option value="kanagawa">神奈川県</option>
</optgroup>
<optgroup label="関西">
<option value="osaka">大阪府</option>
<option value="kyoto">京都府</option>
</optgroup>
</select>
<optgroup> タグを使うと、選択肢をグループ分けして見やすくできます。また、<select multiple> を付けると複数選択が可能になります。
テキストエリア
お問い合わせ内容やコメントなど、複数行のテキストを入力してもらうときに使います。
<label for="s2">お問い合わせ内容:</label><br>
<textarea id="s2" name="message" rows="4" cols="40"
placeholder="内容を入力してください"></textarea>
rows で初期表示の行数、cols で横幅の文字数を指定します。実際のサイズはCSSで制御するのが一般的です。
チェックボックスとラジオボタン
チェックボックスは複数選択可能、ラジオボタンは1つだけ選択可能です。
興味のある分野(複数選択可):
経験レベル(1つ選択):
<!-- チェックボックス(複数選択可能) -->
<p>興味のある分野(複数選択可):</p>
<label><input type="checkbox" name="interest" value="html"> HTML</label>
<label><input type="checkbox" name="interest" value="css"> CSS</label>
<label><input type="checkbox" name="interest" value="js"> JavaScript</label>
<!-- ラジオボタン(1つだけ選択可能) -->
<p>経験レベル(1つ選択):</p>
<label><input type="radio" name="level" value="beginner"> 初心者</label>
<label><input type="radio" name="level" value="intermediate"> 中級者</label>
<label><input type="radio" name="level" value="advanced"> 上級者</label>
チェックボックスは複数選択可能、ラジオボタンは1つだけ選択可能です。ラジオボタンは同じ name 属性を持つものがグループとして扱われます。一度選択すると選択解除できないため、「未選択」の状態が必要な場合は「選択しない」という選択肢を用意しましょう。
チェックボックスやラジオボタンでは、<label> タグで <input> とテキストをまとめて囲む書き方がよく使われます。この書き方なら for / id を省略でき、テキスト部分をクリックしても選択できるようになります。
Step 4HTML5バリデーション属性
HTML5では、JavaScriptを使わずにHTMLの属性だけで入力値のチェック(バリデーション)ができます。ブラウザが自動でエラーメッセージを表示してくれるため、簡単なチェックはこれだけで十分です。
<form>
<label for="v1">名前(必須):</label>
<input type="text" id="v1" name="name" required>
<label for="v2">年齢(1〜120):</label>
<input type="number" id="v2" name="age" min="1" max="120">
<label for="v3">ユーザーID(3〜10文字):</label>
<input type="text" id="v3" name="userid" minlength="3" maxlength="10">
<label for="v4">郵便番号(パターン):</label>
<input type="text" id="v4" name="zip"
pattern="[0-9]{3}-[0-9]{4}" placeholder="123-4567">
<button type="submit">送信</button>
</form>
主なバリデーション属性の一覧です:
| 属性 | 対象 | 説明 |
|---|---|---|
required | すべての入力要素 | 入力必須にする |
min | number, date, range | 最小値を指定 |
max | number, date, range | 最大値を指定 |
minlength | text, password, textarea | 最小文字数を指定 |
maxlength | text, password, textarea | 最大文字数を指定 |
pattern | text, password, tel | 正規表現でパターン指定 |
step | number, range, date | 入力値の刻み幅を指定 |
pattern 属性では正規表現を使ってカスタムルールを設定できます。例えば [0-9]{3}-[0-9]{4} は「数字3桁 - 数字4桁」という形式(郵便番号)にマッチします。title 属性を併用すると、エラー時にヒントメッセージを表示できます。
よく使うバリデーションの組み合わせ
<!-- メールアドレス(必須) -->
<input type="email" name="email" required
placeholder="example@mail.com">
<!-- 電話番号(ハイフンあり) -->
<input type="tel" name="phone"
pattern="[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}"
title="電話番号をハイフン付きで入力してください">
<!-- パスワード(8文字以上、英数字必須) -->
<input type="password" name="password" required
minlength="8"
pattern="(?=.*[a-zA-Z])(?=.*[0-9]).{8,}"
title="英字と数字を含む8文字以上で入力してください">
HTML5バリデーションはブラウザ側のチェックなので、開発者ツールで簡単に無効化できます。サーバー側でも必ずバリデーションを行いましょう。HTML5バリデーションはあくまでユーザーの入力ミスを防ぐ補助的な機能です。
Step 5フォームのスタイリングとアクセシビリティ
フォームを使いやすくするために、適切な構造化とアクセシビリティ対応が重要です。<fieldset> と <legend> で入力グループをまとめることができます。
<form>
<fieldset>
<legend>個人情報</legend>
<label for="a1">名前:</label>
<input type="text" id="a1" name="name" required>
<br><br>
<label for="a2">メール:</label>
<input type="email" id="a2" name="email" required>
</fieldset>
<fieldset>
<legend>アンケート</legend>
<p>利用目的:</p>
<label><input type="checkbox" name="purpose" value="study"> 学習</label>
<label><input type="checkbox" name="purpose" value="work"> 仕事</label>
<label><input type="checkbox" name="purpose" value="hobby"> 趣味</label>
</fieldset>
<button type="submit">送信</button>
</form>
アクセシビリティのためのポイント:
<label>のfor属性と<input>のidを必ず紐づける<fieldset>と<legend>で関連する入力をグループ化するplaceholderはヒントとして使い、<label>の代わりにしない- 必須項目には
required属性を付け、視覚的にも「必須」と表示する - エラーメッセージは具体的に(「入力してください」ではなく「名前を入力してください」)
- キーボードだけでもフォーム全体を操作できるようにする(Tab キーでの移動)
disabled は入力を無効化し、フォーム送信時にもデータが送られません。readonly は編集不可ですが、フォーム送信時にデータが送られます。ユーザーに値を確認させつつ変更させたくない場合は readonly を使いましょう。
Step 6フォーム送信とmethod(GET/POST)
フォームのデータは action 属性で送信先を、method 属性で送信方法を指定します。
<!-- GETメソッド:検索フォーム -->
<form action="/search" method="GET">
<label for="m1">検索:</label>
<input type="text" id="m1" name="q" placeholder="キーワードを入力">
<button type="submit">検索</button>
</form>
<!-- POSTメソッド:ログインフォーム -->
<form action="/login" method="POST">
<label for="m2">ユーザー名:</label>
<input type="text" id="m2" name="username">
<br><br>
<label for="m3">パスワード:</label>
<input type="password" id="m3" name="password">
<br><br>
<button type="submit">ログイン</button>
</form>
GETとPOSTの違い:
| 特徴 | GET | POST |
|---|---|---|
| データの送信場所 | URLのクエリパラメータ | リクエスト本文(body) |
| URLに表示 | される(?q=keyword) | されない |
| データ量 | 制限あり(URL長制限) | 大量のデータも送信可能 |
| 適した用途 | 検索、フィルタリング | ログイン、データ登録・更新 |
| セキュリティ | 低い(URLに露出) | 比較的高い |
| ブックマーク | 可能 | 不可 |
パスワードや個人情報など、機密性のあるデータは必ず POST メソッドを使用しましょう。GET はURLにデータが含まれるため、ブラウザの履歴やサーバーログに残ってしまいます。
フォーム送信時、サーバーに送られるデータは name 属性の値がキーになります。name 属性がない <input> のデータは送信されません。必ず設定しましょう。
enctype属性(ファイルアップロード時)
ファイルをアップロードするフォームでは、enctype 属性を指定する必要があります。
<!-- ファイルアップロード用フォーム -->
<form action="/upload" method="POST" enctype="multipart/form-data">
<label for="file">ファイルを選択:</label>
<input type="file" id="file" name="file" accept=".jpg,.png,.pdf">
<button type="submit">アップロード</button>
</form>
| enctype | 用途 |
|---|---|
application/x-www-form-urlencoded | デフォルト。テキストデータの送信 |
multipart/form-data | ファイルアップロード時に必須 |
まとめ
- フォームは
<form>+<label>+<input>が基本構成 type属性で入力形式を指定する(text, email, password, number, date 等)<select>、<textarea>、チェックボックス、ラジオボタンで多様な入力に対応- HTML5バリデーション属性(required, min, max, pattern 等)で入力チェックができる
<fieldset>と<legend>でグループ化し、アクセシビリティを向上させる- GETは検索向き、POSTはデータ送信向き。機密データは必ずPOSTを使う
- ファイルアップロード時は
enctype="multipart/form-data"を忘れずに