JavaScriptなしでサイドバーの一部分だけを追従させる動作を作ってみます。
※もちろんサイドバーの中身全体を追従させることも、同様の方法でできます!
目次
基本のコード
<div class="column-wrap">
<div class="main-column">
メインカラム
</div>
<div class="sidebar">
<div>追従しないエリア</div>
<div class="sticky">
追従するエリア
</div>
</div>
</div>
.column-wrap{
/*2カラムにするコード*/
display: grid;
grid-template-columns: 1fr minmax(30%,200px);
gap: 20px;
}
.main-column{
/*スクロールの確認のために高さを仮で確保*/
height: 200vh;
}
.sticky{
/*追従させたい要素*/
position: sticky;
top: 0;
}
基本のコードの説明
position:stickyでスクロール追従させるには以下の2つが必要です
- sticky と一緒に top:0; などtopからの距離を書く。
- 親要素の高さが十分にある
というのも以下のように動作するからです。
- 要素が画面の上(top)から0pxの位置にきたら追従開始(top:0の場合)
- 親要素の範囲を超えて追従することはない
なぜかついてこない?親要素の高さを確認してみよう
「position:stickyを書いたのになぜかついてこない」というときは、親要素の高さが小さくなっていないか確認してみましょう。
もしこんな感じで、.stickyの要素の親要素(以下の例だと.sidebar-inner)の高さが小さいと
.stickyは親要素から飛び出せないので全く追従しない、ということになります。
応用パターン:追従位置をもう少しコントロールする
デモでは、もう少し追従位置を実用的にコントロールしています。
ヘッダーの分だけ位置をずらす
デモではヘッダーも追従ヘッダーにしているため、top:0(画面上端に固定)だとヘッダーに隠れてしまいます。
そこで、top:100px(画面上端から100pxの位置に固定)とすることでちょうどよい位置に持ってきます。
親要素の下端より早く止める
デモではバナー画像が親要素の下端より早く止まっています。
デモの場合は、position:stickyで追従する要素そのものの下にpadding-bottomを付けています。
また、親要素の方にpadding-bottomを付けた場合も同様に、paddingの内側で止まります。
まとめ
- position:stickyを使えば、サイドバーの一部分(あるいは中身すべて)をスクロールに追従させることができる
- stickyは一緒にtop:○pxのように、画面のどの端からどんな距離に表示するか指定が必要
- 親要素の範囲を超えられない。動かないときは親要素のサイズが動かしたい大きさまで伸びてるかをチェック!
理解するまで「なぜか動かないときがある」stickyですが、理解できればJavaScriptなしでできることが増えますのでぜひ使ってみましょう!
コメント