CSSの「:checked」を使いこなす:状態管理をDOMからスタイルへ解放せよ
フロントエンドの世界で、僕らが最も頭を悩ませるのが「状態」の管理だ。ボタンを押したらメニューが開く、選択したら色が変わる。これらをいちいちJavaScriptで `classList.add(‘is-active’)` して管理していれば、コードはすぐに肥大化し、スパゲッティ化する。
だが、CSSの `:checked` 擬似クラスを使いこなせば、その泥沼から脱出できる。今日は、ただの「チェックボックスのスタイル変更」にとどまらない、実務で使える「状態駆動型」のCSS設計について語ろう。
—
1. なぜ :checked が最強の武器になるのか
`:checked` は、`` や `` が選択状態にある時にトリガーされる擬似クラスだ。
ブラウザのレンダリングエンジンは、この「チェック状態」を非常に効率的にトラッキングしている。JavaScriptでイベントを購読してDOMを操作するよりも、ブラウザのネイティブな状態管理に寄り添う方が、パフォーマンス面でも、コードの可読性でも圧倒的に有利だ。
基本的な挙動の裏側
ブラウザはチェックボックスの状態が変わるたびに、再計算(Recalculation)をトリガーする。CSSで `:checked` を使っていれば、この再計算のタイミングでスタイルが自動的に適用される。つまり、僕らがJSで書くべき「状態変更ロジック」を、HTMLとCSSの宣言的な関係性の中に隠蔽できるということだ。
—
2. 現場で使える「チェックボックスハック」の実践
実務でよく遭遇する「カスタムUI」のケースを見てみよう。JavaScriptを一切書かずに、トグルスイッチを作るテクニックだ。
サンプルコード:CSSのみで完結するトグルスイッチ
/ チェックボックス自体は隠すのが鉄則 /
.toggle-input {
display: none;
}
/ ラベルをトグルの外枠として機能させる /
.toggle-label {
display: inline-block;
width: 50px;
height: 25px;
background-color: #ccc;
border-radius: 25px;
position: relative;
cursor: pointer;
transition: background-color 0.3s;
}
/ 中の丸いパーツ /
.toggle-label::after {
content: ”;
position: absolute;
top: 3px;
left: 3px;
width: 19px;
height: 19px;
background-color: white;
border-radius: 50%;
transition: transform 0.3s;
}
/ 肝心要の :checked の制御 /
/ 隣接兄弟結合子(+)を使って、チェック状態の時だけスタイルを上書き /
.toggle-input:checked + .toggle-label {
background-color: #4caf50;
}
.toggle-input:checked + .toggle-label::after {
transform: translateX(25px);
}
このコードの肝は、「状態を持つ要素(input)」と「見た目を持つ要素(label)」を切り離し、セレクタの組み合わせ(今回は隣接兄弟結合子 `+`)で連動させている点にある。これがCSSアーキテクチャにおける「関心の分離」の極致だ。
—
3. 実務で「やってはいけないこと」と「ベターな選択」
中級者へのアドバイスとして、ここだけは注意してほしい。
- アクセシビリティを殺すな:
よくある間違いが、`display: none;` でinputを消しすぎて、キーボードフォーカスが当たらなくなることだ。`opacity: 0;` で視覚的に消すか、`clip` プロパティを使ってスクリーンリーダーには認識させつつ、画面からは消すのがプロの仕事だ。
- 複雑すぎる状態管理は避ける:
`:checked` で何でも解決しようとすると、CSSが複雑になりすぎてメンテナンス不能になる。2つ以上の状態が絡み合うような複雑なロジックは、無理せずJSに任せる勇気を持とう。CSSの役割は「状態に応じた見た目の変化」であり、「複雑なビジネスロジックの記述」ではない。
—
最後に:CSSを「宣言的」に書くということ
フロントエンド開発の本質は、状態の管理にある。CSSをただの装飾ツールとしてではなく、「DOMの今の状態を視覚化するための宣言型エンジン」として捉えてみてほしい。
`:checked` を使いこなすことは、ブラウザの仕様を信頼し、コードの行数を減らし、結果としてバグの温床を一つ消し去ることと同義だ。
今日からあなたのプロジェクトで、JSの `if` 文を一つ削って、その代わりにこの `:checked` を仕込んでみてくれ。その快適さに、きっと驚くはずだ。
もし分からないことがあれば、いつでもコードを持ってきてくれ。現場の最前線で、また議論しよう。

コメント