Webサイトで「追尾メニュー」「サイドバー目次」などを実装する際、
position: sticky を使ったのに なぜか全く追尾しない という経験はないでしょうか。
本記事では、実際に私がハマった事例をもとに、
- sticky が効かない本当の原因
- DevTools(開発者ツール)での正しい確認方法
- html / body の overflow が原因だったケースの解決策
を、再現手順付きで解説します。
position: sticky が効かないときにありがちな勘違い
まず、以下のような CSS を書いても追尾しないケースがあります。
.category-toc {
position: sticky;
top: 100px;
}よくある勘違いは次のようなものです。
position: stickyを指定したのに動かないtopも指定している- 親要素に
overflow: hiddenは付けていないつもり
それでも動かない場合、sticky 自体は正しく当たっているのに、構造上殺されている 可能性があります。
まず確認すべきこと(DevToolsでのチェック方法)
Chrome(Edge)で DevTools を開き、Console タブで以下を確認します。
const el = document.querySelector('.category-toc');
getComputedStyle(el).position
getComputedStyle(el).top
getComputedStyle(el).overflowメモ
初めての方は allow pasting を手動で入力すればOK
正常な状態の目安
position: "sticky"
top: "100px"
overflow: "visible"ここが正しければ、sticky指定そのものは失敗していません。
それでも追尾しない場合、次を疑います。
stickyが効かない最大の原因:html / body の overflow
今回の原因は html と body の overflow 設定でした。
Consoleで調べると、以下のような状態になっていました。
{
scrollingElement: 'html',
htmlOverflow: 'hidden auto',
bodyOverflow: 'auto'
}これは実質的に:
- html:
overflow-x: hidden; overflow-y: auto - body:
overflow: auto
という スクロールコンテナが二重になっている状態です。
なぜ html / body の overflow が sticky を壊すのか
position: sticky は、
- 一番近いスクロールコンテナ
- もしくは viewport
を基準に動作します。
しかし、
- html がスクロール
- body もスクロール可能
- さらにラッパー要素が存在
という構成になると、sticky の基準が不安定になり、 結果として「見た目上まったく追尾しない」状態になります。
解決策:スクロールは html に任せ、body は通常フローに戻す
最も安定した解決策は以下です。
html {
overflow-x: hidden;
overflow-y: auto;
}
body {
overflow: visible;
}ポイント
- 縦スクロールは html に一本化
- body を
overflow: autoにしない - 横スクロール防止の
overflow-x: hiddenはOK
この設定を入れた瞬間、 それまで動かなかった sticky が 即座に正常動作しました。
一時的に確認したい場合(Consoleでのテスト)
CSSを編集する前に、Consoleで一時的に試すこともできます。
document.documentElement.style.overflowY = 'auto';
document.documentElement.style.overflowX = 'hidden';
document.body.style.overflow = 'visible';これで追尾するなら、原因は overflow 設定で確定です。
よくある「再発原因」への注意
以下のような実装があると、再び sticky が壊れます。
- モーダル実装で常時
html { overflow: hidden } - レイアウト都合で
body { overflow: auto } height: 100vh+ overflow 制御のラッパー
モーダル用にスクロールを止めたい場合は、 通常時は auto、モーダル時だけ hidden にするのがおすすめです。
html {
overflow-y: auto;
overflow-x: hidden;
}
.modal-open html {
overflow: hidden;
}まとめ:stickyが効かないときはここを疑う
positionやtopが正しくても安心しない- 親要素だけでなく html / body の overflow を必ず確認
- スクロールコンテナは 1つに統一する
sticky が効かない問題は CSS の書き方よりも、 「どこがスクロールしているか」 が原因であることが非常に多いです。
同じことで悩んでいる方の参考になれば幸いです。




