HTML
この記事では、フォームの未入力を防ぐHTMLのrequired属性と、ブラウザが行う入力チェックの基本を説明します。
The required attribute tells the browser not to allow the form to be submitted if the input field is empty.
<input required>
- はじめに
- required 属性とは
- 対応要素と作用範囲
- ブラウザのデフォルト挙動
- コードで学ぶ基本パターン
- 制約検証 API(Constraint Validation API)
- CSS でのスタイリング
- アクセシビリティと aria-required
- よくある落とし穴 & トラブルシューティング
- ベストプラクティス集
はじめに
required は 値の未入力をフォーム送信前に防止する 最も手軽な方法です。ブラウザはユーザーの入力を監視し、空欄のまま送信しようとすると自動でエラーメッセージとハイライトを表示します。
required 属性とは
- 属性型
- Boolean 属性(値を持たず存在すれば真)
- 対象要素
<input>,<select>,<textarea>(ただしtype="hidden"やdisabled等は除外)- 役割
- 「値が空なら送信不可」という valueMissing 制約を自動付与
対応要素と作用範囲
- 入力系 <input>
text/email/url/tel/password/number… など大半のタイプで利用可。- ラジオボタン
- 同じ
nameを持つグループのどれか 1 つが選択されれば制約は満たされます。 - チェックボックス
- 1 個だけに
requiredを付けると「チェック必須」を示せます。複数必須なら JavaScript 併用。 <select>size="1"かつmultiple無しの場合、placeholder option が自動的に必須判定に利用されます。
ブラウザのデフォルト挙動
- 未入力で 送信ボタンをクリック
- ブラウザが valueMissing を検出
- フォーカス移動+ネイティブエラーバルーン表示
- ユーザーが入力 → 制約クリア
デフォルトメッセージは OS 言語に依存し、自動ローカライズされます。
コードで学ぶ基本パターン
HTML
<form>
<label for="email">メール:</label>
<input id="email" type="email" required>
<button type="submit">送信</button>
</form>
空欄送信 → ブラウザがブロック
値入力 → 送信成功
制約検証 API(Constraint Validation API)
input.required- true/false を返す
-
JavaScript
if (el.required) … input.checkValidity()- boolean 返却のみ
-
JavaScript
form.checkValidity() input.reportValidity()- UI と一緒に検証
-
JavaScript
el.reportValidity() input.setCustomValidity(msg)- 独自エラー文
-
JavaScript
emailInput.addEventListener('input', e => { if (e.target.validity.valueMissing) { e.target.setCustomValidity('メールは必須です'); } else { e.target.setCustomValidity(''); } });
CSS でのスタイリング
CSS
input:required:invalid { border: 2px solid red; }
input:required:valid { border: 2px solid green; }
input:optional { opacity: .8; }
:required / :optional で有無を判定
:valid / :invalid と組み合わせて状態別デザイン
アクセシビリティと aria-required
スクリーンリーダーは多くの場合 required を自動アナウンスしますが、カスタム UI や旧ブラウザを考慮し aria-required="true" を明示すると確実。
- 役割
- 視覚的・プログラム的両面から「必須」を伝達。
エラーメッセージは role="alert" または aria-live="assertive" を併用し即時読み上げ。
よくある落とし穴 & トラブルシューティング
inputを JS でdisabled→ 再度有効化しても検証されないdisabledは制約検証対象外- DOM で属性を外した後
reportValidity() form.submit()を呼ぶとバリデーションが走らない- 仕様
- 代わりに
form.requestSubmit()かボタンの.click()を使用 - Safari で動的に
requiredを追加しても即検証しない - フォーカス移動時に再評価
reportValidity()を呼ぶ<select>で最初の空valueオプションが選ばれたまま- プレースホルダー扱い
disabledhiddenselected属性で明示的に除外
ベストプラクティス集
- 視覚 + プログラム両面で必須を示す(ラベル横アスタリスク+
required) - 最小限の必須項目に留め、離脱率を下げる
- サーバー側でも必須チェックを行い二重化
- カスタムメッセージはユーザーに具体的指示を与える
- 多言語サイトでは
lang属性とsetCustomValidity()でローカライズ - グループ入力(複数チェックボックス等)は JS で総合判定
- モバイルではネイティブキーボード種別(
type="email"等)も併用