🍣

Next.js の Skipping auto-scroll behavior ワーニングの解消方法

2024/11/04に公開

🌼 はじめに

Next.js で開発をしていたとき、以下のワーニングが発生しました。

Skipping auto-scroll behavior due to position: sticky or position: fixed on element: ...

私は解消でいるワーニングはできるだけ見つけ次第解消しちゃいたいので、色々調べました。その結果3つほど解決方法がわかったので共有したいと思います。

1. 原因

まず、このワーニングが表示される原因について説明します。

Next.js にはページ遷移時に自動でページのトップにスクロールさせる機能があります。新しいページに遷移したらトップから表示されるように、Next.js が自動的にスクロール位置をリセットしてくれます。

しかし、position: stickyposition: fixed を持つ要素は、その特性上スクロール位置を独自に保持・調整するため、Next.js の自動スクロール処理を干渉し、スクロール動作が予期せぬ動きをすることがあるようです。

そのため「position: stickyposition: fixed の要素があるから、ページ遷移時の自動スクロールリセットをスキップしたよ」というワーニングが表示されるようになったのです。

2. 解決案

では解決案を紹介します

2-1. scrollfalse にする

このワーニングを検索したら1番よく出てくる解決案です。

Linkscroll={false} を設定するか、

<Link href="/some-path" scroll={false}>
  ページリンク
</Link>

router を使ってるならオプションで scroll: false を設定します。

router.push("/some-path", { scroll: false });

通常新しいページに移動したときはトップまでスクロールしますが、scroll: false を設定すると、その自動スクロールを無効にします。これにより、Next.js はスクロール位置を変更しないので、position: stickyposition: fixed を持つ要素がスクロールに干渉することがなくなり、ワーニングも発生しなくなります。

ですが、正直この解決案はあまり役に立たなかったです…(^_^)
だって新しいページに遷移したのにスクロール位置が前のページと同じままだと、違和感ありますよね。

まあ window.scrollTo(0, 0) とかで手動でトップにスクロールさせる方法もありますが、毎回やるのがめんどうくさかったです。

とうことで今回この方法は採用されませんでした。

2-2. stickyfixed 要素を div で囲む

次の解決案は sticky もしくは fixed 要素を div で囲む方法です。

export const Header = () => {
  return (
    <div>
      <header style={{ position: 'sticky', top: 0, background: 'white', zIndex: 10 }}>
        Header
      </header>
    </div>
  );
}

stickyfixed 要素を div で囲むことで、これらの要素が新しい親要素のコンテキストの中に置かれます。これにより、Next.js の自動スクロール処理が親要素に対して適用されるようになり、直接的な干渉を避けることができます。

ただし、この方法はレイアウトや見た目にも影響が出る可能性があります(z-indexが絡んだら特に)。

実際試してみたら、ワーニングが解消されたけど重なりの順序が思う通りにならなかったのでこの方法も今回採用されなかったです。

2-3. stickyfixed 要素の前に div をおく

最後は、sticky もしくは fixed 要素の前に div をおく方法です。

export const Header = () => {
  return (
    <>
      <div></div>
      <header style={{ position: 'sticky', top: 0, background: 'white', zIndex: 10 }}>
        Header
      </header>
    </>
  );
}

stickyfixed 要素の前に div を置くことで、その div に基づいてスクロール位置が決定されるので要素の挙動が明確になります。これにより、Next.js の自動スクロールが意図通りに動作しやすくなります。

この方法をためしたら見た目や機能も邪魔しないし、ワーニングも解消できたので、最終的にこの方法が採用されました。

🌷 終わり

気になって色々調べたのですが、以外にあまり情報がなかったんですよね。この記事がお役に立てれば嬉しいです。

GitHubで編集を提案

Discussion