ユーザーが実際に操作した後にのみ、フォーム入力の検証結果に応じてスタイルを適用する擬似クラスです。:invalidと違いページ表示直後の未入力フォームが赤くならないため、実用的なバリデーション表示がCSSだけで実現できます。
:user-valid / :user-invalidinput:user-invalid {
border-color: #dc2626;
background: #fef2f2;
}
input:user-valid {
border-color: #16a34a;
}操作後にのみエラー/成功の見た目を適用
.field:has(input:user-invalid) .error-message {
display: block;
}:has()と組み合わせてエラーメッセージの表示を制御
「操作した後」の判定(フォーカスを外した時など)はブラウザが適切に行ってくれるため、JSでtouched状態を管理する必要がありません。:has()との組み合わせでエラー文言の出し分けまでCSSで完結します。
:invalidをそのまま使うと、ページを開いた瞬間から必須項目が全部エラー表示になります。ユーザー向けのスタイルには:user-invalidを使い、:invalidはJSからの状態参照など内部用途に留めるのが現代的な使い分けです。
AIはフォームバリデーションの見た目に:invalid直付け(初期表示から赤くなる欠陥UI)か、JSでtouched/dirtyフラグを管理する重い実装を提案しがちです。:user-invalidを知らないAIも多いので、「:user-valid/:user-invalidを使って」と明示すると質の高いコードが出ます。
このフォームのバリデーション表示を、初期表示では赤くならないように:user-invalidベースで実装して
Reactのtouchedフラグでやっているエラー表示切替を、:user-invalidと:has()のCSSに寄せられるか検討して
そのままAIチャットに貼り付けて使える依頼文の例です。ページ上部の「AI用にコピー」でこのページ全体をコンテキストとして渡せます。