:has() で必須フォームのエラー演出
CSS :has() セレクタを活用し、HTML5 の :valid / :invalid 疑似クラスとと組み合わせて、JavaScript ゼロでフォーム入力状態に応じた装飾・送信ボタンの活性化を実現する。
解説
このフォームは、入力エラーの表示と送信ボタンの活性・非活性の切り替えを JavaScript なしで実現しています。要になるのは :has() と入力状態を表す擬似クラスの組み合わせで、.hf__field:has(input:invalid:not(:placeholder-shown)) は「値が空ではないのに形式が不正な入力欄」だけを選びます。条件に合うと枠が赤くなり、軽い揺れアニメーションでエラーを知らせます。:not(:placeholder-shown) を挟むことで、まだ何も打っていない最初の状態でいきなり赤くならない配慮が入っています。
ログインや会員登録、問い合わせフォームなど、メール形式やパスワードの最小文字数を満たしてほしい場面に向きます。required や minlength といった HTML 標準の属性をそのまま検証条件に使えるため、追加のバリデーション用スクリプトを書かずに済むのが魅力です。
カスタマイズと注意点
- エラー色は赤系の値を、揺れの強さや時間は
animationの値を調整します。 - 検証ルールは HTML 側の
typeやrequired、minlengthを変えるだけで増減できます。 - 色だけに頼ると色覚特性のある人に伝わりにくいので、アイコンや文言など色以外の手がかりも添えると親切です。送信処理自体はサーバー側の検証も併用してください。
よくある質問
最初の表示でエラーが赤くならないのはなぜですか?
セレクタに :not(:placeholder-shown) を入れているためです。これにより、まだ何も入力していない欄は対象外になり、ユーザーが一度値を打ってから形式が不正なときだけ赤く表示されます。空欄でいきなり叱られる不快感を避けられます。
検証ルールを増やしたいときはどうしますか?
HTML の input に required や minlength、pattern などの標準属性を足すだけで検証条件を変えられます。CSS 側の :invalid 判定がそのまま新しいルールに反応するので、追加の JavaScript は不要です。