bootstrapを使ったwebアプリケーションをつくっている時に、position: stickyを使ってサイドのナビゲーションバーを追従させたかったのですが、意外に手間取ったのでメモ。
ちなみに環境はbootstrap3だったので、4から新設された<div class=”position-sticky”>…</div>などの位置ユーティリティはそもそも使っていない前提です。
position: stickyが効かない状況
スクロールをして、ヘッダーが見えなくなったあたりでサイドバーに追尾してほしいのですが、ついてきてくれない。
サンプルコードのように、ついて来て欲しい要素にposition: stickyを記しているはずなのになんで来てくれないのかと憤怒してました。
冗長かもしれませんが、見た目でわかりやすくするためにheightなどを入れています。
<body>
<header>
ヘッダーだよ
</header>
<main>
<div class="container">
<div class="row">
<div class="content col-sm-8">
heyhey
</div>
<div class="side-nav col-sm-4">
追従したい
</div>
</div>
</div>
</div>
</main>
<footer>
フッターだよ
</footer>
</body>
header {
background-color: black;
color: white;
height: 100px;
margin-bottom: 50px;
}
main {
margin-bottom: 50px;
}
.container {
background-color: white;
height: 1500px;
}
.content {
background-color: blue;
color: white;
height: 700px;
}
.side-nav {
background-color: yellow;
position: sticky;
}
footer {
background-color: black;
color: white;
height: 100px;
}
解説と解決方法
position: stickyは、一つ上の要素内で動ける余白があった場合にその余白内でのみ画面を追従します。
サンプルコードの場合、.side-navに対してpositionを設定しているので、.rowの余白でですね。
さて、ここで問題になるのが.colです。.col-sm-4にはもともとposition: relativeが入っているので、ここをいじるとせっかくのbootstrapでの整頓が崩れてしまいます。
今回間違いだったのは、追従したい要素に並列で.col-sm-4を入れてしまったことです。
これを分離し親要素に持ってくることで、.side-navは.col-sm-4の入れ子の中で移動できます。
もう一つ忘れてはいけないのが、topを指定すること。これが、パソコンの画面上部〇〇pxに来たら要素の追従を始めるかを決める値になります。
修正した部分はこちら
<div class="row">
<div class="content col-sm-8">
heyhey
</div>
<!-- colを分離する -->
<div class="col-sm-4">
<div class="side-nav">
追従したい
</div>
</div>
</div>
.side-nav {
background-color: yellow;
height: 200px;
width: 100%;
/* 大切 */
position: sticky;
top: 30px;
}
綺麗についてくるようになりました。
bootstrapを使わずに実装をしていてstickyが効かない人は、こちらが参考になるかもしれません。
コメントを残す