サイドバーをスクロールに合わせて追従させる際、position:sticky で実装しようとして少し迷う点があったので、実装方法についてメモ。
サンプルコード
例として、以下のようなシンプルなHTMLで実装してみます。
1 2 3 4 5 6 7 8 | < div class = "content" > < div class = "main" > < p >コンテンツサンプル</ p > 〜 略 〜 < p >コンテンツサンプル</ p > </ div > < div class = "sub" >サイドバー</ div > </ div > |
display: flex でサイドバーを配置して、.subにposition: sticky を設定します。
1 2 3 4 5 6 7 | .content { display : flex ; } . sub { position : sticky; top : 0 ; } |
これで問題ないかと思ったのですが、追従されませんでした。
うまくいかなかった場合のデモページ
追従されない原因は各要素に背景色をつけるとわかりやすいですが、.subの高さが親要素の.contentと同じだけ引き伸ばされているためです。
1 2 3 4 5 6 7 8 9 10 11 12 | .content { display : flex ; background : red ; } .main { background : blue ; } . sub { position : sticky; top : 0 ; background : green ; } |
align-items: flex-start を設定して、親要素と同じだけ高さを引き伸ばさないようにすることで解消できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | .content { display : flex ; align-items : flex-start; background : red ; } .main { background : blue ; } . sub { position : sticky; top : 0 ; background : green ; } |
別の方法として、.sub 内にインナー要素を追加して、その要素に対してposition:sticky を設定するでもよさそうです。
1 2 3 4 5 6 7 8 9 10 | < div class = "content" > < div class = "main" > < p >コンテンツサンプル</ p > 〜 略 〜 < p >コンテンツサンプル</ p > </ div > < div class = "sub" > < div class = "sub_inner" >サイドバー</ div > </ div > </ div > |
.sub_inner に対してposition: sticky の設定を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .content { display : flex ; background : red ; } .main { background : blue ; } . sub { background : green ; } .sub_inner { position : sticky; top : 0 ; background : gold; } |
コメントが承認されるまで時間がかかります。