:user-invalid でフォームエラーを「触った後」だけ出す
必須欄が空のまま赤い枠になるのを避け、ユーザーが入力して離れた/送信したあとに初めてエラー表示するには :invalid ではなく :user-invalid を使う。
どんな時に使う?
必須入力やメール形式チェックなどで、ページ表示直後から空欄がエラー色になってしまうのをやめたいとき。blur/touched クラスを JS で管理する代わりに、ブラウザの疑似クラスに任せられる。
コード/手順
エラー見た目は :invalid ではなく :user-invalid(成功側は :user-valid)に当てる。
css
input:user-invalid,
select:user-invalid,
textarea:user-invalid {
border-color: #d93025;
background-color: #fce8e6;
}
input:user-invalid + .error-msg {
display: block;
}:invalidはrequiredの空欄など、制約を満たさない瞬間からマッチする(ロード直後も含む)。:user-invalidは、ユーザーが値を変えてフォーカスを外したあと、またはフォーム送信を試みたあとに、まだ不正なときだけマッチする。- 色だけに頼らず、アイコンやヘルパーテキストなど別チャネルでもエラーを示す。
aria-invalidは CSS だけでは同期されない。必要ならel.matches(':user-invalid')で属性を書き換える小さな JS を併用する。
注意点・対応状況
- Baseline Widely available(Chrome / Edge 119+、Firefox 88+、Safari 16.5+)。未対応環境向けには
.user-invalid-fallbackクラスを blur/input で付けるフォールバックを用意する。 - 「ユーザーが触った」の判定タイミングはブラウザ実装に依存する。送信試行後に一度マッチし、その後また触ると状態が戻ることがある。
- カスタムバリデーション(
setCustomValidity)でも:user-invalidは効くが、制約なしのただの<input>にはマッチしない。