フォームバリデーションの「最後の砦」:`:in-range` と `:out-of-range` を使い倒す
現場でバリデーションを実装する際、JavaScriptでガリガリとロジックを組んでエラーメッセージを出し分ける……それも一つの正攻法だ。だが、ブラウザがネイティブで持っている「強力な武器」を無視するのは、エンジニアとして少しもったいない。
今日は、数値入力のバリデーションにおいて、CSSだけで完結する極めてスマートな解決策、`:in-range` と `:out-of-range` について深掘りしよう。中級者なら、ここをマスターするだけで「UXの質」が一段階跳ね上がるはずだ。
—
なぜ JavaScript に頼り切ってはいけないのか
もちろん、複雑なビジネスロジックはJSが必要だ。しかし、「単純な範囲指定」であれば話は別だ。`min` や `max` 属性をHTMLに書くだけで、ブラウザは内部的にその要素が「許容範囲内か否か」を常に監視している。
このブラウザの内部状態をCSS側で直接フックできるのが、`:in-range` と `:out-of-range` だ。JSで `input` イベントを監視してクラスを付け替える……そんな泥臭いDOM操作をせずとも、CSSだけで「今の値は範囲外ですよ」とユーザーに視覚的なフィードバックを即座に返せる。これがモダンなフロントエンドの流儀だ。
実務で使える:洗練された実装サンプル
ただ枠を赤くするだけでは芸がない。ユーザーが「なぜエラーなのか」を直感的に理解できる、実務レベルのスタイルを組んでみよう。
/ 基準となるスタイル /
.input-field {
padding: 10px;
border: 2px solid #ccc;
border-radius: 4px;
transition: border-color 0.3s ease;
}
/ 範囲内のとき:安心感を与える緑 /
.input-field:in-range {
border-color: #2ecc71;
}
/ 範囲外のとき:注意を促す赤 /
.input-field:out-of-range {
border-color: #e74c3c;
background-color: #fdf2f2;
}
/ エラーメッセージの表示制御 /
.error-message {
display: none;
color: #e74c3c;
font-size: 0.8rem;
margin-top: 5px;
}
/ 範囲外のときだけメッセージを表示 /
.input-field:out-of-range + .error-message {
display: block;
}
この疑似クラスが教えてくれる「ブラウザの裏側」
ここで一つ注意点がある。この疑似クラスは、「値が空(空文字)」のときは適用されないという仕様になっている。
これは初心者が最もハマるポイントだ。`min=”10″` と設定していても、ユーザーが数値をすべて消して空欄にした瞬間、`:out-of-range` は発火しない。なぜなら、ブラウザにとって「空」は「範囲外」ではなく「未入力」という別の状態だからだ。
もし「空のときもエラーにしたい」のであれば、`:required` 疑似クラスや、`:invalid` を組み合わせる必要がある。ここが、CSSだけでバリデーションを組む際の「読み」の深さが出る部分だ。
シニアエンジニアからのワンポイントアドバイス
現場でこの機能を導入する際、以下の3点を意識しておくとチームメンバーからの評価がグッと上がる。
1. アクセシビリティを忘れるな: 色だけでエラーを伝えてはいけない。必ずアイコンを添えるか、上記コードのようにメッセージ領域を確保すること。
2. ブラウザの挙動を過信しない: 非常に古いブラウザや、極めて特殊な入力デバイスでは挙動が怪しいこともある。最終的なバリデーションは必ずサーバーサイド、あるいはJSのバリデーションライブラリで担保する「二段構え」が鉄則だ。
3. `:invalid` との使い分け: `:invalid` は「形式(型やパターン)」が合わないときに発火する。一方、`:out-of-range` は「形式は正しいが、数値の範囲が合わない」ときに発火する。この意味論的な使い分けこそが、メンテナンス性の高いCSSを生む。
まとめ
`:in-range` と `:out-of-range` は、単なるスタイル付けのための疑似クラスではない。HTMLの構造とブラウザのバリデーション機能をCSSに橋渡しする、極めて優秀なインターフェースだ。
「とりあえずJSで頑張る」という選択肢を捨て、まずはCSSで表現できるUIを突き詰めてみてほしい。コードは短くなり、ブラウザの負荷も下がり、何より「余計なJSを書かない」という選択が、あなたの書くアプリケーションをより堅牢なものにするはずだ。
次は、フォームの `pattern` 属性と `:invalid` を組み合わせて、正規表現バリデーションをCSSだけで完結させるテクニックを試してみるといい。また一段と視界が開けるはずだよ。

コメント