CSSのスムーススクロールscroll-behavior:smooth時にページ内検索の移動は除外する
CSS でスムーススクロールができる scroll-behavior というプロパティがあります。たった 1 行指定するだけで簡単に実装できてしまうので便利な反面、ユーザビリティの点で問題があります。
ページ内検索の問題
スムーススクロールを指定すると、ページ内検索まで滑らかにスクロールされるようになります。
これではページ内に検索した単語が複数あるとき、目的の情報までたどりつくのに時間がかかってしまいます。
救世主:focus-within
擬似クラス :focus-within は子孫要素の中に :focus 状態の要素があれば適用されます。それを利用して :focus 状態のときにだけスムーススクロールされるようにしています。
<a href="#jump">見出しへ</a>
...
<h2 id="jump" tabindex="-1">...</h2>
html:focus-within {
scroll-behavior: smooth;
}
しかし、この解決策ではページ内リンクをクリックしたときに Chrome と Firefox でスムーススクロールされなくなってしまいます。
最適解
scroll-behavior: smooth; を指定した 2 つのアニメーションを用意し、:focus されたときにアニメーションを切り替えることでページ検索のときだけスムーススクロールが除外されるようにしています。
<a href="#jump">見出しへ</a>
...
<h2 id="jump">...</h2>
@keyframes smooth-scroll-1 {
0%, 100% {
scroll-behavior: smooth;
}
}
@keyframes smooth-scroll-2 {
0%, 100% {
scroll-behavior: smooth;
}
}
html {
animation: smooth-scroll-1 1s;
}
html:focus-within {
animation-name: smooth-scroll-2;
scroll-behavior: smooth;
}
先ほどの手法と違って tabindex="-1" を指定する必要もなく、CSS だけで完結する解決策なので汎用性も高いです。
@supports not selector(::-internal-media-controls-overlay-cast-button) {
html {
scroll-behavior: smooth;
}
}
また、このテクニックを使うと Safari でスムーススクロールされなくなってしまうため、CSS ハックを使って Chrome 以外のブラウザの場合はそのまま scroll-behavior が適用されるようにしておきます。
この ::-internal-media-controls-overlay-cast-button は非推奨の擬似クラスのため、今後他のブラウザで実装されることはなく安全な CSS ハックです。
デモ
この記事が気に入ったらサポートをしてみませんか?