CSS Stickyが効かない?サイドバーで使うためのベストプラクティスとよくあるNGパターン
はじめに
position: sticky;は非常に便利なCSSプロパティですが、うまく動作しないことがあります。この記事では、サイドバーでstickyを効果的に使うためのベストプラクティスと、避けるべきNGパターンについて解説します。
よくあるパターン
よくあるパターンをコードを添えて書きます。
例では以下のようなシンプルな HTMLに css を当てていくとします。(動作例は codepen で確認ください。)
<div class="container">
<div class="left-container">
<div class="content">メインコンテンツ</div>
</div>
<div class="right-container">
<div class="content">サイドコンテンツ0</div>
<div class="content">サイドコンテンツ1</div>
</div>
</div>
パターン1: スティッキーを上部に固定
.container-1 {
display: flex;
.right-container {
position: sticky;
top: 0;
align-self: flex-start;
}
}
この方法では、.right-containerが上部に固定されます。top: 0; の位置で固定となります。サイドバーのコンテンツの高さが小さい場合につかえる単純なパターンです。
パターン2: スティッキーを下部に固定
.container-2 {
display: flex;
.right-container {
align-self: flex-end;
position: sticky;
bottom: 0;
}
}
ここでは、.right-containerが下部に固定されます。bottom: 0;の位置で固定となります。サイドバーのコンテンツの高さが小さければ使える単純なパターンです。後述するパターン5のがよく使うかもしれません。
パターン3: 最後の要素だけ、スティッキーで上部に固定
.container-3 {
display: flex;
.right-container {
.content:last-of-type {
position: sticky;
top: 0;
}
}
}
このパターンでは、最初に.contentの最後の子要素が上部に固定されて、最後がボトムで揃うように動きます。余ったサイドバーに空白をなくせるので、広告枠などによく使われます。
パターン4: 最初の要素をスティッキーで下部に固定
.container-4 {
display: flex;
.right-container {
display: flex;
flex-direction: column;
justify-content: flex-end;
.content:first-of-type {
position: sticky;
bottom: 0;
}
}
}
.contentの最初の子要素が下部に固定されます。こちらはよくあるとまでは言い切れないかもしれません。
パターン5: サイドコンテンツが高さに応じて、上部または、下部で固定する
.container-5 {
display: flex;
.right-container {
align-self: flex-end;
position: sticky;
bottom: 0;
min-height: 100vh;
}
}
こちらは、.right-containerの高さが動的に変わる場合に有用です。
codepen で、サイドバーの高さがメインより小さい場合は上部に固定されて、サイドバーの高さがメインより大きい場合は下部に固定されているのが確認できます。
NGパターン: Stickyが効かない時のチェックリスト
もしうまくいかない場合、よくハマるポイントがあるので以下チェックしてみてください。
親要素でのoverflow: hidden が設定されていないか
親要素や祖先要素にoverflow: hiddenが設定されていると、stickyは効きません。overflow-x: hidden も設定されていると効きません。
スティッキー要素の親要素の高さが足りているか
親要素が十分な高さを持っていない場合、stickyは効きません。
今回は利用してませんが、float 使った場合など、親要素がスティッキー要素の高さと同じになっている場合があります。親要素の高さ > スティッキー要素 でないと動作しません。
スティッキー要素が stretch または、100% の高さになっていないか
スティッキー要素が親要素に対して100%の高さを持つ場合も、親要素の高さ > スティッキー要素でないので動作しません。
flexを設定すると、align-items: stretch は設定しなくてもデフォルトで設定される(つまり 100%の高さになる)ので、 と flex と sticky を利用した場合、align-items か align-self が必要です。
スティッキー要素に正確なtopまたはbottomが設定されていない
topやbottomの値が正しく設定されていないと、stickyは期待通りに動作しない可能性があります。
まとめ
CSSのposition: sticky;を用いたサイドバーのデザインは非常に便利ですが、意外にハマってしまうので注意が必要です。この記事で紹介したベストプラクティスとNGパターンを頭に入れて、無駄な時間が防げたら幸いです!
もし参考になれば、いいねもらえると大変励みになります。
Discussion