overflow: clip — position: sticky が壊れる問題の解決策
TL;DR:
overflow: hiddenの代わりにoverflow: clipを使えば、sticky はそのまま動き、はみ出しも隠せる。
問題
こういうレイアウトで詰まったことはないですか? overflow: hidden のコンテナの中に sticky ヘッダーを入れているケース:
<div class="wrapper"> <!-- overflow: hidden がここに 👈 -->
<header class="sticky">Sticky Header</header>
<main>...長いコンテンツ...</main>
</div>
.wrapper {
overflow: hidden; /* ❌ 内側の sticky を無効化してしまう */
}
.sticky {
position: sticky;
top: 0; /* 動かない! */
}
結果: ヘッダーは普通にスクロールされ、sticky にならない。
なぜそうなるのか?
overflow: hidden は新しいスクロールコンテナを生成する。ブラウザは .sticky を「このコンテナの中だけで sticky」と解釈する。コンテナ自体がスクロールしないので、sticky が意味をなさなくなる。
┌─────────────────────────────────────┐
│ viewport(ここでスクロールする) │
│ ┌───────────────────────────────┐ │
│ │ .wrapper (overflow: hidden) │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ .sticky ← 誰に対して │ │ │
│ │ │ sticky?wrapper は │ │ │
│ │ │ スクロールしない! │ │ │
│ │ └─────────────────────────┘ │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
解決策:overflow: clip
.wrapper {
overflow: clip; /* ✅ はみ出しを隠しつつ、スクロールコンテナを作らない */
}
.sticky {
position: sticky;
top: 0; /* ちゃんと動く! */
}
overflow: clip と overflow: hidden の違い:
overflow: hidden |
overflow: clip |
|
|---|---|---|
| はみ出しを隠す | ✅ | ✅ |
| スクロールコンテナを生成 | ✅ | ❌ |
position: sticky を壊す |
✅ | ❌ |
| ブラウザサポート | すべて | Chrome 90+, Firefox 102+, Safari 16+ |
実例
修正前(バグあり)
/* ❌ sticky が効かない */
.card-container {
overflow: hidden;
border-radius: 12px;
}
.card-header {
position: sticky;
top: 0;
background: white;
z-index: 10;
}
修正後(正常動作)
/* ✅ 角丸も sticky も両立 */
.card-container {
overflow: clip; /* 角丸のはみ出しをカット */
border-radius: 12px;
}
.card-header {
position: sticky;
top: 0;
background: white;
z-index: 10;
}
軸ごとの制御
overflow: clip は軸ごとに指定できる点も強い:
/* 横だけ clip、縦は visible のまま */
.wrapper {
overflow-x: clip;
overflow-y: visible;
}
これは overflow: hidden では不可能。
ブラウザサポート(2025年)
Chrome 90+ ✅
Firefox 102+ ✅
Safari 16+ ✅
Edge 90+ ✅
本番環境でも安心して使える。
判断フロー
はみ出しを隠したい?
└── 内側に sticky がある?
├── ある → overflow: clip を使う ✅
└── ない → overflow: hidden でも clip でも OK
今後はデフォルトで
overflow: clipを使おう。hiddenと同じことができて、sticky を壊さない。