おい、最近の仕様の進み具合は追ってるか?
フロントエンドの荒波にもまれながら「もっとスマートにフォームのバリデーションやUI制御ができないもんか」と頭を悩ませている中級の君なら、きっと今日のテーマにグッとくるはずだ。
今日は、現在進行形でブラウザの標準化が進められている、非常にエキサイティングな疑似クラス`:blank`について話をしよう。
「あれ、`:empty`なら知ってるよ」と思ったそこの君。惜しい、だがそこが今回の最大のトラップであり、僕たちが長年抱えてきたフォームの闇なんだ。現場のリアルな泥臭さを解消するこの新星について、シニアの視点からみっちり解説してやるから、コーヒーでも飲みながら聞いてくれ。
—
なぜ僕たちは `:empty` では満足できなかったのか?
まず、CSSの歴史に詳しい君ならお馴染みの `:empty` 疑似クラスを思い出してほしい。こいつは「子要素もテキストノードも一切含まない完全な空っぽの要素」にマッチする。
じゃあ、これを``や`
なぜなら、ブラウザの内部実装において、``などの置換要素(Replaced Element)は、たとえユーザーが何も入力していなくてvalueが空文字であっても、DOMツリー上には常に何らかの状態や内部構造を抱えている。だから、DOMのツリー構造ベースで判定する `:empty` にとって、フォーム入力欄は「空ではない」扱いになっちまうんだよ。
僕たちはこれまで、フォームが空かどうかを判定するために、わざわざJavaScriptで `input` イベントを監視して `is-empty` みたいなクラスを泥臭く付与したり、CSSの `:placeholder-shown` という「プレースホルダーが表示されているかどうか」という、本来の目的とはビミョーに意味合いの違う疑似クラスで代用したりしてきた。
……正直、スマートじゃないよな?
`:blank` とは何か? ブラウザの裏側の動き
そこで登場するのが、今回の主役である `:blank` 疑似クラス だ。
input:blank {
/ ユーザーの入力が「空」のときに発動する /
}
この `:blank` は、まさに僕たちが長年待ち望んでいた「ユーザー入力が本当に空である状態」をターゲットにするためのものだ。仕様策定の文脈としては、Selectors Level 4で議論されてきた歴史があり、特にフォームの入力値(value)が空(`””`)である要素にヒットするように設計されている。
ブラウザが裏側でどう処理しているかというと、DOMのテキスト内容やノードの有無だけを見る `:empty` とは異なり、「ユーザーインタラクションによって入力された値(Value)の長さが 0 であるか」という、セマンティックな入力状態を評価している。
これにより、プレースホルダーの有無に依存せず、「本当に入力がされていない状態」を純粋なCSSだけでハンドリングできるようになるんだ。これはフォームのUXを設計する上で、地味だが革命的な進化だと言っていい。
—
現場で即戦力になる! `:blank` 活用スニペット
さて、理論はこの辺にしておいて、実務でどう使うかだ。
前述の通り、`:blank` は実験的な機能(Experimental)であり、ブラウザのサポート状況にはまだ注意が必要だが、モダンブラウザのフラグ有効時や今後の標準化を見据えて、今からコードの引き出しに入れておくべきだ。
ここでは、プレースホルダーが表示されていようがいまいが、ユーザーが入力していない瞬間にフワッとラベルを変化させたり、バリデーションの見た目をコントロールする実践的なコードを紹介しよう。
/ フォームグループ全体のベーススタイル /
.field-group {
position: relative;
margin-bottom: 24px;
}
.field-group input,
.field-group textarea {
width: 100%;
padding: 12px 16px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
outline: none;
transition: border-color 0.2s ease;
}
/
【ここがポイント】
入力欄が「空(:blank)」のとき、フローティングラベルを元の位置(プレースホルダーっぽい場所)に沈めておく。
※ブラウザの実験的実装やフォールバックを考慮する場合の書き方
/
.field-group label {
position: absolute;
left: 16px;
top: 14px;
font-size: 16px;
color: #888;
pointer-events: none;
transition: transform 0.2s ease, font-size 0.2s ease, color 0.2s ease;
transform: translateY(0);
}
/
入力値が存在する、またはフォーカスされているときはラベルを持ち上げる
※実務ではまだ :blank がフルサポートされていない環境もあるため、
:not(:placeholder-shown) や :focus と組み合わせるのが現時点でのベストプラクティス。
しかし、:blank が普及すれば、この判定が劇的にシンプルになる。
/
.field-group input:focus + label,
.field-group input:not(:blank) + label,
.field-group textarea:focus + label,
.field-group textarea:not(:blank) + label {
transform: translateY(-28px);
font-size: 12px;
color: #0066cc;
}
/ 入力中のボーダー制御 /
.field-group input:focus,
.field-group textarea:focus {
border-color: #0066cc;
}
/
もし入力が空のままでフォーカスが外れた(blur)場合のスタイリング
実務的なエラー表示の演出にも応用可能
/
.field-group input:user-invalid:blank {
border-color: #ff3333;
}
このコードのミソは、`:not(:blank)` を使うことで、「プレースホルダーが設定されていない入力欄であっても、文字が入力された瞬間にラベルの状態を切り替えられる」という点にある。従来の `:placeholder-shown` では、プレースホルダー属性(`placeholder=”…”`)をHTMLに必ず記述しなければ挙動が破綻するという縛りがあったが、`:blank` ならその呪縛から解放されるんだ。
—
シニアからの実務アドバイス:明日の開発にどう向き合うか
ここまで読んで「よっしゃ、明日の案件のプロダクションコードに全部 `:blank` ぶち込んでやるぜ!」と思ったなら、ちょっと待て。そこは場数を踏んだプロとしてブレーキを踏ませてくれ。
冒頭でも言った通り、`:blank` は現在仕様策定中、あるいはブラウザの実験的機能(Experimental)の段階だ。2024〜2025年現在、すべてのモダンブラウザでデフォルト有効になっているわけではない。
だからこそ、現場での立ち回りはこうするんだ:
1. プログレッシブ・エンハンスメント(段階的enhancement)の精神を忘れない
メインのロジックやバリデーションをCSSの `:blank` だけに依存させないこと。JavaScriptによるフォールバックや、従来の `:placeholder-shown` との併用を視野に入れた設計にすること。
2. キャッチアップのアンテナを張り巡らせる
CSS Working Groupの仕様変更や、Can I useなどのサポート状況を定期的にチェックする。「あいつ、新しい仕様にやたら詳しいな」と思われるエンジニアは、こういう実験的機能の背景とユースケースを誰よりも早く検証している奴のことだ。
仕様の波にただ流されるんじゃなく、技術の本質を見極めて自分の武器にする。
今日の `:blank` の話が、君のフロントエンドエンジニアとしての引き出しを一つ広げるきっかけになったなら、シニアとしてこれ以上嬉しいことはないね。
さあ、エディタを開いて、まずはローカルの環境でこの実験的な疑似クラスの動きを試してみようぜ!

コメント