Hiratake Web ロゴ

固定ヘッダーを position: sticky; で実装したページで scroll-padding-top を使ってハマった

投稿した日
更新した日
書いたひと
icon
ひらたけ

ウェブページの上部にヘッダーを固定するときに 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 なども動いているページだったこともあり原因が中々分からず困っていたのですが、調べていくと以下の投稿が見つかりました。

どうもそういう不具合があるっぽい。知らなすぎる。


ヘッダーを固定することも、id 属性を付けてページ内の特定の位置に飛ばせるようにすることも、どちらもよくある内容なので、また同じように困ることがありそうだなーと思い自分用の備忘録的な感じで書くなどしました。改善されるまでは大人しく fixed でヘッダーを固定するのが良いのかなー。