そろそろ使える :focus-within
疑似クラス
Selectors Level 4 で規定されている :focus-within
疑似クラスですが、既に Firefox 52 と Safari 10.1 では使えるようになっており、 Chrome も8月リリース予定のバージョン60からデフォルトで有効になります。
- Selectors Level 4 仕様(
drafts.csswg.org
) - Can I use...
これは :focus
疑似クラスが適用される要素、またはそのような要素を子孫に含む要素に対して適用されます。
これまで、
<span class="check-container">
<input type="checkbox" id="check1"><label for="check1">チェックボックス</label>
</span>
のようなチェックボックスに対して、「チェックボックスにフォーカスが当たったとき、チェックボックスとラベルを囲う祖先要素にスタイルを適用する」ということはできませんでしたが、 :focus-within
疑似クラスを使えば
.check-container:focus-within {
background: yellow;
}
とすることで実現可能です。
CSSのみで作るドロップダウンメニュー
応用例として、ドロップダウンメニューのようなものをCSSのみで実現することが可能になります。
<style>
.nav .nav-sub {
display: none;
}
`
.nav > li:focus-within .nav-sub {
display: block;
}
</style>
<ul class="nav">
<li><span tabindex="0">カテゴリ1</span>
<div class="nav-sub">
<ul>
<li><a href="">カテゴリ1-1</a></li>
<li><a href="">カテゴリ1-2</a></li>
</ul>
</div>
</li>
<li><span tabindex="0">カテゴリ2</span>
<div class="nav-sub">
<ul>
<li><a href="">カテゴリ2-1</a></li>
<li><a href="">カテゴリ2-2</a></li>
</ul>
</div>
</li>
</ul>
これまでも「CSSのみで作るドロップダウンメニュー」というものは存在しましたが、 :hover
疑似クラスを使ったものであり、要するにPCでのマウス操作を前提にしていたため、タッチデバイスやキーボード操作では操作不能でした。
今後は :focus-within
を使うことにより、 JavaScript を使うことなくタッチデバイスやキーボード操作にも対応することが可能になります。
ドロップダウンメニューに JavaScript は不要になるのか
では、今後あらゆるドロップダウンメニューは JavaScript 要らずになるのかといえば、そうではありません。上記のサンプルコードは display: none
で表示/非表示を切り替えていますが、 transition
でアニメーションを付けるために height: 0
や opacity: 0
にしたいケースもあるでしょう。そうすると、たとえ見た目上は見えなくとも読み上げやキーボード操作に不都合が出てきます。
例えば、先のサンプルコードで「カテゴリ2」にフォーカスがある状態で Shift + Tab を押すと「カテゴリ1」に戻りますが、CSSを次のように変更して同じ操作をすると「カテゴリ1-2」に戻ってしまいます。
.nav .nav-sub {
opacity: 0;
transition: opacity 1s;
}
.nav > li:focus-within .nav-sub {
opacity: 1;
}
また、 JavaScript を使えば WAI-ARIA の属性を設定することもできるメリットもあります。
結局のところ、動きのあるコンポーネントは今後も JavaScript を使うのが基本という点は変わらないと思います。ただし、「アニメーションは要らない、支援技術に対する考慮も最低限でよい」といったシンプルな要件の場合はCSSのみで素早く実装することができるようになりますね。
ブラウザの対応状況
Firefox, Safari は最新版で対応済み、 Chrome もまもなく対応される一方、 Edge は対応していません。
また、 Firefox には実装バグがあり(1361301 - [selectors4] :focus-within is lost when moving to descendant(bugzilla.mozilla.org
))、先に挙げたドロップダウンメニューの例のように display: none
が絡むケースでキーボード操作がうまく働きませんが、これは8月リリース予定のバージョン55で解消されるようです。
2018年10月11日追記Edgeに関しても開発優先度が "高" に変更されたので(Fix: Change priority for :focus-within pseudo-class
to high
· MicrosoftEdge/Status@acf7906)、まもなく開発が始まるものと思われます。