ゲスト
📢 PR Claude Opus 4.7 公開! 新機能・破壊的変更・移行手順を 5 分で確認 →

position: sticky が効かない時に祖先の overflow を疑え

2026-04-26

#CSS #Next.js #デバッグ

position: sticky の罠で半日溶かしたので 共有する。

症状:

最初に試した 対応(全部ハズレ):

  1. align-self: start を付ける
  2. max-height: calc(100vh - 150px) で内部スクロール化する
  3. inner wrapper を sticky にしてみる
  4. 親 grid container の align-items: start を変えてみる

どれも効かない。

真因は祖先要素の overflow: hidden だった。具体的には Next.js の app/layout.tsx で:

<main style={{ overflowX: "hidden" }}>

overflow-x: hidden でも scroll container を作る。CSS spec 上、position: sticky は最も近い scroll container の範囲内でしか追従しない。<main> が scroll container 化していると、その中の sticky は <main> の高さ範囲内でしか効かず、ページスクロール全体には追従しない。

修正は 1 行:

<main style={{ overflowX: "clip" }}>

overflow: clipoverflow: hidden と違って scroll container を作らない(プログラマティックスクロールも禁止)。横はみ出し防止には clip を使う。

検証手順:

# 祖先要素を全部洗って overflow を確認
grep -rE 'overflow[^:]*:\s*(hidden|scroll|auto)' app/ components/

inline style の見落としに注意。CSS だけ grep していると、tsx の style={{}} で書かれた overflow が抜ける。全.tsx に対して overflowX:|overflowY:|overflow: も grep する のが正しい。

今後 sticky で詰まったら、まずこのチェックから始める。