41
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

よくある「ホバーしたらドロップダウンメニューを表示するナビゲーション」を駆逐したい

Last updated at Posted at 2022-06-12

正確には

ホバーした時だけドロップダウンメニューを表示するナビゲーション」がどうかなぁ、と思っている次第です。
あと駆逐は言いすぎましたごめんなさい。「タイトルは弱く見えるくらい強い言葉を使え」って誰かが言ってたので(出典不明)

どんなやつ?

こんなやつ。

See the Pen Untitled by MenTori (@MentTori) on CodePen.

カーソルでホバーするとドロップダウンでネストしたナビゲーションが表示されます。
多くの情報をスッキリとした見た目に収めることができる、とても素晴らしいUI👍

なにがよくないの?

タブキーでアクセスできないことです。。。この一点だけです😫
画面収録1.gif

タブでアクセスできないなら、タブでアクセスできるようにすればいいじゃない

ということでタブキーでドロップダウンメニュー(以降ドロップメニュー)にアクセスできるようにしよう!!

▼ ゴール
goal.gif

tabindexでフォーカス可能にする

まずデモ実装はドロップメニューのトリガー(以降トリガー)がdiv要素で実装されており、そもそもタブキーではフォーカスがあたらないです。
そのためtabindex属性を指定してフォーカス可能な要素にしてあげましょう!
tabindex属性 - HTML Standard 日本語訳

<div class="link link-hover" tabindex="0">
	product
	<div class="tooltip">
	...

これでタブ移動でフォーカスが当たるようになりました🎉

ドロップメニュー内にフォーカスが移動した後もドロップメニューを表示させる

現状トリガー要素の:hover, :focus擬似クラスにスタイルを定義していて、両者の場合にドロップメニューを表示させています。

/* .link is トリガー */
.link:hover > .dropDown,
.link:focus > .dropDown {
	display: block;
}

このままだとドロップメニュー内にフォーカスが移動すると上記のスタイルが適用されずに、ドロップメニューが非表示となってしまいます。これでは、いけませんね。
画面収録2.gif

ということで、「トリガーの子要素にフォーカスが当たっている場合に」という状況のスタイルを定義します。
そこで登場するのが:focus-within擬似クラスです!
:focus-within - CSS: カスケーディングスタイルシート | MDN

こちらは

その要素または子孫要素にフォーカスがある場合に一致します。

ということで、なんとも今回の状況にベストマッチしてくれている擬似クラスですね。
「その要素または」ということでトリガーにフォーカスがある場合にも適用されるので、今回の場合:focus擬似クラスをこちらの擬似クラスに書き換えれば万事解決ということになります!

.link:hover > .dropDown,
.link:focus-within > .dropDown {
	display: block;
}

完成

以下が完成形のデモとなります!
タブでドロップメニューにアクセスできるよ!やったね!!👏

See the Pen Accessible by tab key by MenTori (@MentTori) on CodePen.

41
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?