固定ヘッダーを position: sticky; で実装したページで scroll-padding-top を使ってハマった
- 投稿した日
- 更新した日
- 書いたひと
- ひらたけ
ウェブページの上部にヘッダーを固定するときに position: sticky;
を使って実装していたページで、アンカーリンクへ飛んだときに固定のヘッダーと重ならないよう scroll-padding-top
を指定したら変な動きが発生してハマった話です。CSS なんもわからん。
ヘッダーを固定する際、大多数のページは position: fixed;
で実装している印象ですが、この fixed
を指定してしまうと 要素が通常のフローから外れてしまい次にある要素と重なって表示されてしまう という問題があります。
margin-top
などを指定することで調整は可能なのですが、ヘッダーの高さが固定ではない場合などに不便なので、先日私が作っていたページでは以下の記事のように position: sticky;
を使って実装するという方法を取っていました。
そしてヘッダーを固定している場合、上部には常にヘッダーが表示されているため アンカーリンク(ページ内リンク)を使うとコンテンツがヘッダーと重なってしまう という問題が発生するのですが、この問題を解決するために scroll-padding-top
というプロパティを html
タグに指定して調整していました。
この方法はうまくいき、ちゃんと ヘッダーは固定されてアンカーリンクへ飛んでもコンテンツとヘッダーが重ならない状態 となったのですが、何故か ヘッダー内のテキストを選択したりテキストボックスに文字入力したりすると画面がスクロールする という現象が起こりました。
<!DOCTYPE html>
<html lang="ja" class="scroll-pt-16">
<head>
<meta charset="UTF-8" />
</head>
<body class="relative">
<header class="sticky top-0 bg-white shadow-lg">
<div>Page Title</div>
</header>
<main>
<p>コンテンツ</p>
</main>
</body>
</html>
こういう HTML があったときに、画面の下までスクロールした状態で sticky
を使って固定しているヘッダーにある「Page Title」をカーソルをドラッグして選択すると、ページが勝手に上へとスクロールするのです(以下のリンクはサンプル)。
色々 JavaScript なども動いているページだったこともあり原因が中々分からず困っていたのですが、調べていくと以下の投稿が見つかりました。
- css - Scrolling bug when focusing element inside position sticky container - Stack Overflow
- scroll automatic when input keypress (40749247) - Chromium
どうもそういう不具合があるっぽい。知らなすぎる。
ヘッダーを固定することも、id
属性を付けてページ内の特定の位置に飛ばせるようにすることも、どちらもよくある内容なので、また同じように困ることがありそうだなーと思い自分用の備忘録的な感じで書くなどしました。改善されるまでは大人しく fixed
でヘッダーを固定するのが良いのかなー。