note 毎日更新してます

【css】bootstrap利用でposition:stickyが効かない時の解決方法

bootstrapを使ったwebアプリケーションをつくっている時に、position: stickyを使ってサイドのナビゲーションバーを追従させたかったのですが、意外に手間取ったのでメモ。

ちなみに環境はbootstrap3だったので、4から新設された<div class=”position-sticky”>…</div>などの位置ユーティリティはそもそも使っていない前提です。

position: stickyが効かない状況

スクロールをして、ヘッダーが見えなくなったあたりでサイドバーに追尾してほしいのですが、ついてきてくれない。

サンプルコードのように、ついて来て欲しい要素にposition: stickyを記しているはずなのになんで来てくれないのかと憤怒してました。

サンプルコード

冗長かもしれませんが、見た目でわかりやすくするためにheightなどを入れています。

HTML
<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>
CSS
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;
}
参考 サンプルサイトNainaism

解説と解決方法

position: stickyは、一つ上の要素内で動ける余白があった場合にその余白内でのみ画面を追従します。

サンプルコードの場合、.side-navに対してpositionを設定しているので、.rowの余白でですね。

さて、ここで問題になるのが.colです。.col-sm-4にはもともとposition: relativeが入っているので、ここをいじるとせっかくのbootstrapでの整頓が崩れてしまいます。

今回間違いだったのは、追従したい要素に並列で.col-sm-4を入れてしまったことです。

これを分離し親要素に持ってくることで、.side-navは.col-sm-4の入れ子の中で移動できます。

もう一つ忘れてはいけないのが、topを指定すること。これが、パソコンの画面上部〇〇pxに来たら要素の追従を始めるかを決める値になります。

修正した部分はこちら

修正部分
HTML
<div class="row">
  <div class="content col-sm-8">
    heyhey
  </div>
  <!-- colを分離する -->
  <div class="col-sm-4">
    <div class="side-nav">
      追従したい
    </div>
  </div>
</div>
CSS
.side-nav {
  background-color: yellow;
  height: 200px;
  width: 100%;
  /* 大切 */
  position: sticky;
  top: 30px;
}
参考 修正後サンプルNainaism

綺麗についてくるようになりました。

bootstrapを使わずに実装をしていてstickyが効かない人は、こちらが参考になるかもしれません。

https://sota-jp.com/blog/1221.html

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です