😀

stickyでサイドバーが固定されない時に確認したいこと

2020/06/24に公開

CSSでサイドバーを固定するのにposition: sitckyは便利ですよね。

一部対応されていないブラウザがあるものの、JavaScriptを使わなくてもよいので利用している人も多いのではないでしょうか。
そんな便利なstickyですが指定しているのに固定されないという経験はありませんか?

正しく仕様を理解していないとハマってしまうこともあると思います。
今回はstickyを指定しているけどうまく固定されない場合に確認したいことを紹介します。

stickyと合わせてtopを指定する

stickyの用途でもっとも基本的なことはサイドバーが一定以上スクロールされた場合に、特定の要素を画面の上に固定させることだと思います。

まず意図した通りに固定されない時、確認したいのはtopを指定しているかです。

stickyだけ指定すれば画面の上にぴったり固定できそうですが、その場合でもtopの指定が必要になります。

.sidebar {
  position: sticky;
  top: 0;  // 画面の一番上に固定する場合
}

topの値は0だけでなく画面の上から離したいだけの数値を指定すれば大丈夫です。

<RelatedPost slug="sidebar-sticky-css" />

flexで横並びにしている要素にstickyは使えない

stickyが効かない原因の理由はflexを指定した子要素を固定しようとしている場合が多いかもしれません。

flexを使うことで横並びの要素は高さが同一になるためstickyの仕様上、要素を固定できません。

たとえば2カラムのHTMLとして下記のようなコードはよくあると思います。

<div class="content">
  <div class="main"></div>
  <div class="side"></div>
</div>

この場合mainとsideを横並びにしてsideをstickyで固定したい場合、下記のようなCSSが自然です。

.content {
  display: flex;
}

.main {
  width: 728px;
}

.side {
  flex: 1;
  position: sticky;
  top: 0;
}

自然のように見えるこのコードはstickyで固定できません。
先に触れたようにflexを使うことでmainとsideの高さが同一になるためです。

横並びにはHTMLを入れ子にする

flexを使っている要素を固定する場合にはHTMLを入れ子にすることで回避可能です。
具体的には先に紹介したsideの中に固定するための要素を追加します。

<div class="content">
  <div class="main"></div>
  <div class="side">
    <div class="sticky">
      固定したい要素
    </div>
  </div>
</div>

**sideの中で入れ子にすることで、固定する要素がmainと同じ高さになるのを防ぐことができます。 **

CSSも入れ子した要素に当てます。

.sticky {
  position: sticky;
  top: 0;
}

これでflexを使って横並びしている要素に対してもstickyで固定できます。

まとめ

stickyで固定されない原因は今回紹介したパターンが多いように思います。
特にflexと一緒に使うパターンは自然なCSSでもあるので、ハマりがちかもしれません。

正しく使えばstickyはとても簡単に要素を固定できる便利な方法なので、仕様をちゃんと理解しつつ積極的に使いたいプロパティです。

Discussion