マガジン

フォームの入力チェックとエラーメッセージ:HTML標準でできる範囲とAIへの頼み方

AIを使いこなす

Claudeで執筆し、GPTで自動校閲・修正しています。

入力欄を模した紙に、説明用の付箋を添える手元
記事の内容をもとに制作したAI生成イメージです。実際の製品画面や検証結果の写真ではありません。

結論から言うと、「空欄でないか」「メール形式か」「文字数や数値が範囲内か」「決まった文字の並びか」までは、HTMLの属性だけで入力チェックができます。required、type、minlength/maxlength、min/max、pattern を付ければ、JavaScriptなしでブラウザが送信前に止めてくれます。 HTMLだけで手が届かないのは、主にエラー文の言い回しを細かく整えることと、複数の入力欄をまたぐチェック(例:パスワードと確認用の一致)です。ここから先は少量のJavaScriptの出番で、AIに頼む価値もここにあります。 この記事のコード例は、説明用の例です。実際のブラウザで動作確認したものではないので、使う前に自分の環境で試してください。

この記事の目次
  1. HTMLの属性でできること:用途表
  2. エラーメッセージを直しやすくする書き換え例
  3. 見えるヒントと「触ったあとだけ」のエラー表示
  4. 日本語のメッセージに差し替える最小のJavaScript
  5. AIへの頼み方:渡す情報と、人が確認すること
  6. どこまでHTMLで済ませるかの判断

HTMLの属性でできること:用途表

MDNのフォーム検証の解説で紹介されている組み込みの属性を、初学者が選びやすい形に並べ替えました。「向かない場面」の列は、公式の仕様説明を踏まえた編集上の目安です。

  • required、何をチェックするか:空のまま送信させない、書き方の例:<input required>、向かない場面:「どちらか一方があればよい」という条件
  • type="email"、何をチェックするか:メールアドレスの形式、書き方の例:<input type="email">、向かない場面:実在するアドレスかどうかの確認
  • type="url"、何をチェックするか:URLの形式、書き方の例:<input type="url">、向かない場面:リンク先が生きているかの確認
  • type="number" + min / max / step、何をチェックするか:数値の範囲と刻み、書き方の例:<input type="number" min="1" max="10">、向かない場面:郵便番号など、先頭の0が大事な番号
  • minlength / maxlength、何をチェックするか:文字数の下限・上限、書き方の例:<input minlength="8" maxlength="20">、向かない場面:数値の大小(これは min/max)
  • pattern、何をチェックするか:正規表現に全体一致するか、書き方の例:<input pattern="[a-z]{4,8}">、向かない場面:複雑すぎる規則、複数欄の突き合わせ

pattern で特に押さえたいのは次の点です(MDNのpattern解説より)。

  • 対象は text、tel、email、url、password、search の入力欄です。
  • 値の全体に一致する必要があるので、先頭・末尾を表す記号を自分で付ける必要はありません。
  • 値が空のときは pattern の違反になりません。空欄を許さないなら required も併用します。

郵便番号に type="number" を使わない理由

数値用の欄は、先頭の0が消えたり、桁区切りの扱いが想定とずれたりしやすい種類です。郵便番号や電話番号は「計算しない数字の並び」なので、type="text" や type="tel" に pattern を組み合わせるほうが素直です。これは編集上の提案です。

エラーメッセージを直しやすくする書き換え例

属性を付けるだけでも、ブラウザが標準のエラー文を出します。ただ、文面はブラウザ任せで、「何をどう直せばよいか」まで伝わらない場合があります。pattern に付ける title はエラー文に使われることがあります。ただしMDNは、title だけに頼らず、欄の近くに見えるテキストで規則を示すよう勧めています。

直しやすい文の条件を、次の3点にまとめます(編集上の提案です)。

  1. どの欄かが分かる(「入力が正しくありません」だけにしない)
  2. 何が足りない/多いかを言う
  3. 直した後の形の例を添える

以下は説明用の書き換え例です。

  • メール(空欄)、分かりにくい例:必須項目です、直しやすい例:返信先のメールアドレスを入力してください。
  • メール(形式)、分かりにくい例:無効な形式です、直しやすい例:「name@example.com」のような形式で入力してください。
  • 電話番号、分かりにくい例:パターンに一致しません、直しやすい例:電話番号は数字だけ、10〜11桁で入力してください(例:09012345678)。
  • 郵便番号、分かりにくい例:不正な値です、直しやすい例:郵便番号は数字7桁で入力してください(例:1000001)。ハイフンは不要です。
  • パスワード、分かりにくい例:短すぎます、直しやすい例:パスワードは8文字以上で入力してください。
  • 年齢、分かりにくい例:範囲外です、直しやすい例:年齢は0〜120の数字で入力してください。

「ハイフンは不要です」と書くより、ハイフンありの入力も受け付けて、送信時にプログラム側で取り除くほうが利用者には親切です。その場合は pattern を緩め、整形は別の処理に任せます。どちらを採るかは、フォームの受け手が何を必要とするかで決めてください。

見えるヒントと「触ったあとだけ」のエラー表示

エラー文以前に、規則は最初から見える場所に書いておくのが基本です。web.devでは、aria-describedby で入力欄と説明文を結びつける書き方が紹介されています。

html
<label for="pw">パスワード</label>
<input id="pw" name="pw" type="password" required minlength="8"
       aria-describedby="pw-hint">
<p id="pw-hint">8文字以上で入力してください。</p>

見た目の指定では、:invalid を使うと、入力前の空欄まで最初から赤く表示されます。web.devは、利用者が操作したあとだけ反応する :user-invalid を使えば、早すぎるエラー表示を避けられると説明しています。また、赤い枠だけに頼らず、文字やアイコンも併用するよう勧めています。

css
input:user-invalid { border: 2px solid #b00020; }

:user-invalid は比較的新しい疑似クラスなので、公開前に自分が対象とするブラウザで見え方を確認してください。対応状況はこの記事では調べていません。

日本語のメッセージに差し替える最小のJavaScript

文言を自分で指定したいときは、Constraint Validation APIの setCustomValidity() を使います。MDNとweb.devの両方で紹介されている方法です。どの種類の違反かは validity.valueMissing、typeMismatch、patternMismatch などで判別できます。

これは説明用の例で、未実行です。

js
const messages = {
  email: {
    valueMissing: "返信先のメールアドレスを入力してください。",
    typeMismatch: "「name@example.com」のような形式で入力してください。"
  },
  tel: {
    valueMissing: "電話番号を入力してください。",
    patternMismatch: "電話番号は数字だけ、10〜11桁で入力してください(例:09012345678)。"
  }
};

document.querySelectorAll("input").forEach((input) => {
  input.addEventListener("invalid", () => {
    input.setCustomValidity("");
    const set = messages[input.name];
    if (!set) return;
    for (const key in set) {
      if (input.validity[key]) {
        input.setCustomValidity(set[key]);
        break;
      }
    }
  });
  input.addEventListener("input", () => input.setCustomValidity(""));
});

最後の input イベントで空文字を設定しているのは、カスタムメッセージが残ったままだと、直した後も「無効」と扱われるためです。MDNの例でも、再検証の前にメッセージを空に戻しています。

対応する HTML 側は次のようになります。

html
<form>
  <input name="email" type="email" required>
  <input name="tel" type="tel" required pattern="[0-9]{10,11}">
  <button>送信</button>
</form>

AIへの頼み方:渡す情報と、人が確認すること

AIには「まずHTML属性だけで」と範囲を指定すると、不要なライブラリや大きなスクリプトを避けられます。下の依頼文をそのまま使えます。

text
次のフォームに、HTMLの属性だけで入力チェックを付けてください。
- 欄:お名前(必須)、メール(必須)、電話番号(任意・数字10〜11桁)、年齢(任意・0〜120)
- 使ってよいもの:required, type, minlength, maxlength, min, max, pattern
- 各欄の下に、規則を書いた説明文を置き、aria-describedby で結ぶこと
- 属性だけでは足りない部分は、理由とともに別に挙げること
- そのあと、各違反(空欄・形式・桁数・範囲)ごとに、
  「どの欄か/何をどう直すか/入力例」を含む日本語のエラー文を表にすること
- JavaScriptは、その表の文言に差し替える60行以内のものだけ

人が確認すべき点は次のとおりです。

  • 正規表現を実例で試す。 自分が通したい入力と、止めたい入力を各3つほど用意し、実際にブラウザで送信して確かめます。AIの「このパターンで合っています」は検証結果ではありません。
  • 任意欄を空のまま送る。 pattern は空の値では違反にならないので、任意欄が通ることを確かめます。
  • サーバー側の検証は別に必要。 MDNは、クライアント側の検証はセキュリティ対策ではないと明記しています。通信内容は悪意ある利用者が書き換えられるため、受け取る側のチェックも必須です。
  • 個人情報を渡さない。 AIに貼るのは項目名や架空の入力例だけにし、実在の顧客データは置き換えてください。

どこまでHTMLで済ませるかの判断

  • 必須、形式、文字数、数値範囲、単純な形式、方針:HTMLの属性だけで足りる
  • エラー文を自然な日本語にしたい、方針:属性+setCustomValidity() の小さなスクリプト
  • 2つの欄の一致、「どちらか一方が必須」、方針:JavaScriptで独自チェック
  • メールの実在、重複登録、在庫の有無、方針:サーバー側での確認が必要

まず属性で骨組みを作り、エラー文だけを整える。この順で進めると、AIに頼む範囲も小さくなり、動かなかったときの原因も見つけやすくなります。

出典・参考資料