sticky TOCが効かないときは親グリッドのitems-startを疑う
Next.js/Tailwind CSSでsticky TOC(目次)を実装したのに追従しない、と悩む人向け。原因は親グリッドのitems-startだったケースを、実際にサイト実装で確認した修正手順つきで解説します(2026年7月確認)
- Next.js
- CSS Grid
- sticky
- TOC
- レイアウト
- 他1
右レールに目次(TOC)を置き、position: sticky でスクロールに追従させる。よくある実装です。ところが top の値を調整しても、z-index を足しても、目次が本文と一緒にスクロールで流れていってしまうことがあります。
こういうとき、多くの人はまず TOC 自体の CSS を疑います。position: sticky の書き間違い、top の指定漏れ、overflow: hidden を持つ祖先要素の存在。定番の原因はいくつもあります。ただ、それらを一通り確認しても直らないケースが一つあります。親グリッドの縦揃え。
今日の結論
- sticky が効かないとき、TOC 側だけでなく親グリッドの
align-itemsを疑うitems-start(align-items: start)だと、aside(sticky対象の親)の高さが TOC の中身の分だけに縮み、sticky が張り付くための縦方向の余白が消える- 対処は親を既定の
stretchに戻す、または aside 側に明示的なstretchやmin-heightを指定する- 原因さえ特定できれば、修正はクラス1つの変更で済むことが多い
症状:position: stickyを設定しても目次が追従しない
構成としては、記事レイアウトを CSS Grid で組み、左に本文、右に TOC の aside を配置。aside 側には position: sticky と top を指定済み。それでもスクロールすると、TOC が画面上部で止まらず本文と一緒に流れていくという状態です。
TOC 単体のスタイルを何度見直しても再現しない場合、疑う場所を一段上げる必要があります。
原因:親グリッドのitems-startでasideの高さが縮んでいた
sticky は、要素自身の高さを超える余白がスクロール可能な親の中にある場合にだけ効果を発揮します。親グリッドに align-items: start(または items-start のような Tailwind ユーティリティ)が指定されていると、grid の各アイテムは中身の高さ分までしか伸びない。aside の高さが TOC のコンテンツ分に圧縮され、本文より短くなる。
すると、sticky が縦方向に「浮く」ための遊びがなくなり、見た目上は通常のブロック要素と変わらない挙動になります。TOC のプロパティ自体は正しいのに効かない、という状況はここで起きます。
筆者はこの現象を、サイトデザイン改善の作業中(RichArticleLayout コンポーネント、2026年7月21日確認)に踏みました。親グリッドから items-start を外すだけで、追従しなかった TOC が正しく張り付くようになっています。
対処:親グリッドの縦揃えをstretchに戻す
- 記事全体を包む親グリッド(または flex)のクラスを確認する
items-start/align-items: startが指定されていれば、既定のstretchに戻す(指定を削除するだけで stretch に戻る場合が多い)- 何らかの理由で
items-startを外せない場合は、aside 側にself-stretch(align-self: stretch)または明示的なmin-height: 100%を指定する - スクロールして TOC が画面上部に張り付くか再確認する
親グリッド全体の縦揃えを変えたくない事情がある場合は、aside 単体への上書きで対応可能です。
確認しておきたいチェックリスト
| 確認項目 | 状態 |
|---|---|
対象要素に position: sticky と top の指定があるか | |
祖先要素に overflow: hidden(または auto)が無いか | |
親グリッド/フレックスに align-items: start や align-self: start が指定されていないか | |
| 親コンテナの高さが、TOC の高さより十分に長いか(本文の方が長いか) |
TOC 単体の設定に問題がない場合、上から3番目・4番目の項目が原因になっているケースが多いというのが今回の実測です。
まとめ・次に読む
sticky が効かないときのチェック順は、TOC 自体 → 祖先の overflow → 親グリッドの縦揃え、の3段階で考えると原因にたどり着きやすくなります。TOCクリックで見出しがヘッダーに隠れる場合は、scroll-marginの二重適用を疑う手順も参照してください。Next.js/Vercel 側のレイアウト・反映トラブルは、Vercel で Preview だけ更新されて Production に反映されないときの確認手順 でも似た「効かない・反映されない」系の確認手順をまとめています。
同日公開の次記事として、本文先頭のタイトル二重表示と CRLF の切り分けも整理しています。
CSS Grid・Tailwind CSS の挙動やブラウザ実装は今後変更される可能性があります。本記事は執筆時点(2026-07-22)で確認した内容です。フレームワークのバージョンによって挙動が異なる場合があるため、重要な実装判断は公式ドキュメントで確認してください。