こんにちは。masaです。
みなさんは、CSSでposition: stickyを使おうとした時、「あれ?効かない!」という場面に遭遇し、四苦八苦したことはないでしょうか。
position: stickyは要素を特定のスクロール位置で固定するとても便利なプロパティですが、実は親要素のoverflow設定によっては動かないことがあります。
今回は、この問題をまるっと解決しちゃおうと思います!
position: stickyは、スクロール時に要素に指定されたtopやleftの位置を超えた際に固定される働きをします。
ただし、これは「要素の包含ブロック(containing block)を基準」に行われます。
通常、position: stickyが適用される要素の包含ブロックは「直近のposition: relativeやposition: absolute以外のブロック要素」、且つスクロール可能な親要素になります。
親要素にoverflow: hiddenを指定すると、その要素の「クリッピングコンテキスト(clipping context)」が作成され、子要素がその範囲を超えて表示されなくなります。
この時、position: stickyの固定動作も抑制されるため、スクロールしても要素が親要素内で静止したままになってしまいます。
簡単にまとめると下記が機能しなくなる仕組みです。
さて、ここで登場するのが今回の救世主、overflow: clipです。
overflow: clipを指定した場合、スクロールに関する影響は与えず、単に視覚的なクリッピングを行うため、position: stickyが機能するようになります。
・overflow: hiddenと同様に要素をクリップするが、スクロールやレイアウトには影響を与えない。
・stickyの計算には影響せず、スクロール時に要素を親の外に移動できる。
つまり、視覚的には親要素の範囲を超えないようにクリッピングされるものの、stickyの動作には影響を与えないため、期待通りに機能します。
ではここで実際のコードで比較してみましょう。
/* overflow: hidden の場合(stickyが機能しない) */
.parent {
overflow: hidden;
height: 300px;
border: 1px solid #ccc;
}
.child {
position: sticky;
top: 10px;
background: yellow;
}
/* overflow: clip の場合(stickyが機能する) */
.parent {
overflow: clip;
height: 300px;
border: 1px solid #ccc;
}
.child {
position: sticky;
top: 10px;
background: yellow;
}
そう、overflow: hiddenをoverflow: clipに置き換えただけです。
とても簡単ですよね。
・overflow: hiddenはposition: stickyの動作を妨げる。
・overflow: clipはstickyの動作に影響を与えず、視覚的にのみクリッピングを行う。
・stickyを適用する際、overflowの影響を考慮することが重要。
position: sticky を活用する際は、親要素のoverflow設定に注意し、必要に応じてoverflow: clipを使用することで期待通りの動作を得ることができます。
さあ、もうこれでposition: stickyが怖くないですね!
みなさんもどんどん活用してUXの高いサイトを作ってください!
山口県育ちの音楽大好きおっちゃんです。10年ほど関東にいましたが、Uターンで地元山口に帰ってきました。山口のことや、Webのことなど、さまざまな情報を共有していければと思います。どうぞ何卒よろしくお願いいたします。
REC.