対象: CSS(全モダンブラウザ対応)
難易度: ★☆☆
所要時間: 約5分
ブログ記事のサイドバーにあるプロフィールや目次を、スクロールしても画面内に追従させたい…という要望、よくありますよね。以前はJavaScriptでスクロール位置を監視して座標を計算する、なんて力技が必要でしたが、今はCSSのposition: sticky;だけで実現できます。
position: stickyの基本的な書き方
追従させたい要素に、次の2つを指定するだけです。
.sidebar-profile {
position: sticky;
top: 20px; /* 画面上端から20pxの位置で止まる */
}top: 20px;は「画面の一番上から20pxのところまで来たら、そこで止まって画面に固定される」という意味です。ヘッダーが固定表示(sticky/fixed)になっているサイトなら、ヘッダーの高さ分だけtopの値を大きくしておくと、要素がヘッダーの下に隠れずに済みます。
効かない時に確認すべき3つのポイント
position: sticky;は書いたはずなのに効かない、というのは非常によくあるつまずきポイントです。以下の3つを順番に確認してみてください。
position: sticky;だけでは動きません。top(またはbottom)の値がないと、ブラウザはどこで止めればいいか判断できません。
stickyにしたい要素の親(祖先)要素のいずれかにoverflow: hidden;やoverflow: auto;が指定されていると、sticky指定が無効になります。意外と見落としがちな原因No.1です。
sticky要素は「親要素の範囲内」でしか追従しません。親要素の高さが、sticky要素自体の高さとほぼ同じ(=スクロールする余地がない)場合、追従しているように見えないことがあります。
本文が長く、サイドバーが先に終わってしまう記事だと、追従した要素がフッターに重なって表示されてしまうことがあります。この場合は、サイドバー全体を囲む親要素の高さを本文と同じ高さまで確保しておくか、JavaScriptでフッター手前で追従を止める処理を追加する必要があります。単純なposition: sticky;だけでは対応しきれないケースがある、という点は覚えておいてください。
まとめ
position: sticky;とtopの値をセットで指定するだけで、JavaScript不要で追従表示ができる- 効かない時は「topの指定漏れ」「親要素のoverflow:hidden」「親要素の高さ不足」の3点を疑う
- サイドバーが本文より短い記事では、フッターへの重なりに注意する
