10日で覚えるHTMLDay 7: フォームの応用
books.chapter 710日で覚えるHTML

Day 7: フォームの応用

今日学ぶこと

  • HTML5のバリデーション機能
  • 新しいinputタイプ
  • datalist によるオートコンプリート
  • progress と meter 要素

HTML5バリデーション

HTMLには、JavaScriptを書かずにフォームの入力チェックができる組み込みバリデーション機能があります。

flowchart LR
    Input["ユーザー入力"] --> Validate{"HTML5<br>バリデーション"}
    Validate -->|"✅ 有効"| Submit["送信"]
    Validate -->|"❌ 無効"| Error["エラーメッセージ"]
    Error --> Input
    style Validate fill:#f59e0b,color:#fff
    style Submit fill:#22c55e,color:#fff
    style Error fill:#ef4444,color:#fff

バリデーション属性

属性 説明
required 必須入力 required
minlength 最小文字数 minlength="3"
maxlength 最大文字数 maxlength="100"
min 最小値(数値・日付) min="0"
max 最大値(数値・日付) max="100"
step 入力のステップ step="0.01"
pattern 正規表現パターン pattern="[0-9]{3}"

実例

<form>
    <!-- 必須入力 -->
    <label for="name">名前(必須):</label>
    <input type="text" id="name" name="name" required>

    <!-- 文字数制限 -->
    <label for="username">ユーザー名(3〜20文字):</label>
    <input type="text" id="username" name="username"
           minlength="3" maxlength="20" required>

    <!-- 数値の範囲 -->
    <label for="age">年齢(1〜120):</label>
    <input type="number" id="age" name="age"
           min="1" max="120" required>

    <!-- 正規表現パターン -->
    <label for="zipcode">郵便番号(例: 123-4567):</label>
    <input type="text" id="zipcode" name="zipcode"
           pattern="[0-9]{3}-[0-9]{4}"
           title="半角数字でXXX-XXXXの形式で入力してください"
           required>

    <button type="submit">送信</button>
</form>

ポイント: pattern属性を使う場合、title属性でエラーメッセージのヒントを提供しましょう。


pattern 属性の正規表現

パターン 説明 マッチ例
[0-9]{3} 数字3桁 123
[A-Za-z]+ 英字1文字以上 hello
[0-9]{3}-[0-9]{4} 郵便番号 123-4567
.{8,} 8文字以上 password1
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} メール user@example.com
<!-- 電話番号 -->
<input type="tel" pattern="0[0-9]{1,4}-[0-9]{1,4}-[0-9]{4}"
       title="例: 03-1234-5678">

<!-- パスワード(英数字8文字以上) -->
<input type="password" pattern="(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}"
       title="英字と数字を含む8文字以上">

新しい input タイプ

カラーピッカー

<label for="color">テーマカラー:</label>
<input type="color" id="color" name="color" value="#3b82f6">

ファイルアップロード

<label for="avatar">プロフィール画像:</label>
<input type="file" id="avatar" name="avatar"
       accept="image/png, image/jpeg">

<!-- 複数ファイル -->
<input type="file" name="documents" multiple
       accept=".pdf,.doc,.docx">
属性 説明
accept 受け付けるファイルタイプ
multiple 複数ファイル選択可

hidden input

ユーザーには見えないデータを送信するために使います。

<input type="hidden" name="form_id" value="contact-v2">
<input type="hidden" name="timestamp" value="2026-01-29">

datalist によるオートコンプリート

<datalist>を使うと、入力候補を表示できます。

<label for="browser">ブラウザ:</label>
<input type="text" id="browser" name="browser" list="browsers">
<datalist id="browsers">
    <option value="Chrome">
    <option value="Firefox">
    <option value="Safari">
    <option value="Edge">
    <option value="Opera">
</datalist>

ポイント: <datalist>はあくまで候補を提示するだけで、ユーザーは自由にテキストを入力することもできます。<select>とは異なります。

flowchart LR
    subgraph Comparison["datalist vs select"]
        DL["&lt;datalist&gt;<br>候補提示 + 自由入力"]
        SL["&lt;select&gt;<br>選択肢のみ"]
    end
    style DL fill:#22c55e,color:#fff
    style SL fill:#3b82f6,color:#fff

output 要素

計算結果やスクリプトの出力を表示するセマンティック要素です。

<form oninput="result.value = parseInt(a.value) + parseInt(b.value)">
    <input type="number" id="a" name="a" value="0"> +
    <input type="number" id="b" name="b" value="0"> =
    <output name="result" for="a b">0</output>
</form>

progress と meter

progress(進捗バー)

<label for="download">ダウンロード進捗:</label>
<progress id="download" value="70" max="100">70%</progress>

meter(メーター)

<label for="disk">ディスク使用量:</label>
<meter id="disk" value="65" min="0" max="100"
       low="30" high="80" optimum="20">65%</meter>
要素 用途 属性
<progress> タスクの進捗 value, max
<meter> 計測値の表示 value, min, max, low, high, optimum

フォームのグループ化と構造

fieldset と legend

<form>
    <fieldset>
        <legend>個人情報</legend>
        <p>
            <label for="fname">名前:</label>
            <input type="text" id="fname" name="fname" required>
        </p>
        <p>
            <label for="femail">メール:</label>
            <input type="email" id="femail" name="femail" required>
        </p>
    </fieldset>

    <fieldset>
        <legend>配送情報</legend>
        <p>
            <label for="address">住所:</label>
            <input type="text" id="address" name="address" required>
        </p>
        <p>
            <label for="delivery-date">配送日:</label>
            <input type="date" id="delivery-date" name="delivery-date"
                   min="2026-01-30">
        </p>
    </fieldset>

    <button type="submit">注文する</button>
</form>

実践: ユーザー登録フォーム

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザー登録</title>
</head>
<body>
    <h1>ユーザー登録</h1>

    <form action="/register" method="post">
        <fieldset>
            <legend>アカウント情報</legend>
            <p>
                <label for="reg-username">ユーザー名(3〜20文字):</label><br>
                <input type="text" id="reg-username" name="username"
                       minlength="3" maxlength="20" required
                       pattern="[a-zA-Z0-9_]+"
                       title="英数字とアンダースコアのみ使用可能">
            </p>
            <p>
                <label for="reg-email">メールアドレス:</label><br>
                <input type="email" id="reg-email" name="email" required>
            </p>
            <p>
                <label for="reg-password">パスワード(8文字以上):</label><br>
                <input type="password" id="reg-password" name="password"
                       minlength="8" required>
            </p>
        </fieldset>

        <fieldset>
            <legend>プロフィール</legend>
            <p>
                <label for="reg-birthday">生年月日:</label><br>
                <input type="date" id="reg-birthday" name="birthday">
            </p>
            <p>
                <label for="reg-country">居住国:</label><br>
                <input type="text" id="reg-country" name="country"
                       list="countries">
                <datalist id="countries">
                    <option value="日本">
                    <option value="アメリカ">
                    <option value="イギリス">
                    <option value="カナダ">
                    <option value="オーストラリア">
                </datalist>
            </p>
            <p>
                <label for="reg-color">テーマカラー:</label><br>
                <input type="color" id="reg-color" name="theme_color"
                       value="#3b82f6">
            </p>
            <p>
                <label for="reg-bio">自己紹介:</label><br>
                <textarea id="reg-bio" name="bio" rows="4" cols="50"
                          maxlength="500"
                          placeholder="500文字以内で自己紹介を書いてください"></textarea>
            </p>
        </fieldset>

        <fieldset>
            <legend>通知設定</legend>
            <label>
                <input type="checkbox" name="notify_email" checked>
                メール通知を受け取る
            </label><br>
            <label>
                <input type="checkbox" name="notify_news">
                ニュースレターを受け取る
            </label>
        </fieldset>

        <p>
            <label>
                <input type="checkbox" name="agree" required>
                <a href="/terms">利用規約</a>に同意する
            </label>
        </p>

        <button type="submit">登録する</button>
    </form>
</body>
</html>

まとめ

概念 説明
HTML5バリデーション required, pattern, min/maxなど
pattern 正規表現による入力チェック
<datalist> オートコンプリート候補
<output> 計算結果の出力
<progress> 進捗バー
<meter> 計測値のメーター
type="color" カラーピッカー
type="file" ファイルアップロード

重要ポイント

  1. HTML5バリデーションでサーバー送信前にチェックできる
  2. patterntitleセットで使う
  3. <datalist>は自由入力も許可する柔軟な候補提示
  4. HTML5バリデーションはサーバーサイドバリデーションの代替にはならない

練習問題

問題1: 基本

郵便番号(XXX-XXXX形式)と電話番号(XXX-XXXX-XXXX形式)のバリデーション付きフォームを作成してください。

問題2: 応用

プログラミング言語を選択する<datalist>付きフォームを作成してください。10個以上の候補を含めましょう。

チャレンジ問題

完全なイベント申し込みフォームを作成してください。以下を含めること:

  • 参加者情報(名前、メール、電話)
  • イベント選択(ラジオボタン)
  • 食事制限(チェックボックス)
  • 参加日(date、未来の日付のみ)
  • 備考(textarea)
  • すべての入力に適切なバリデーション

参考リンク


次回予告: Day 8では「セマンティックHTML」について学びます。<header>, <main>, <footer>などのセマンティック要素を使い、意味のあるWebページ構造を作りましょう。