
position: sticky でいろいろなスティッキー(追尾)サイドバーを試す
ブログ的なレイアウトだと、サイドバーをスクロールに合わせて固定させたいということがよくありますよね。一般的にこれは JavaScript で実装されますが、せっかくなので CSS の position: sticky
で試してみました。
position: sticky とは
使用頻度の高い position
プロパティにあって sticky
なる値は聞いたことがないかもしれませんが、これは CSS Positioned Layout Module Level 3 にて追加された新しいもので、なかなか説明するのがムズカシイのですが、fixed
と relative
を合わせたようなものだと MDN では説明されています。
position: sticky
と しきい値 (top, right, bottom, left プロパティ)を指定することで、画面上の絶対位置がしきい値より大きいときは relative
のように、オフセット値に達すると fixed
のように振る舞うという感じです。
対応ブラウザ

Edge と IE が対応していないのでまだ迂闊に使えないかもしれませんが、 未対応が致命的なレイアウト系のプロパティとちがって数%の Edge と IE ユーザーがスティッキーしないだけなので、これが悪影響にならないと判断できれば使い道はありそう。未対応ブラウザのみ JS を使うという手もあります。
Sticky なサイドバーの例たち
百聞は一見にしかずということで、 position: sticky
を使った追尾型サイドバーを何バリエーションか作ってみました。
まずはベーシックなスタイルから。
[codepen_embed height=”432″ theme_id=”light” slug_hash=”vgwMEe” default_tab=”result” user=”holy0201″ preview=”true” data-preview=”true”]See the Pen <a href=’http://codepen.io/holy0201/pen/vgwMEe/’>position: sticky; Sticky sidebar(standard)</a> by holy0201 (<a href=’http://codepen.io/holy0201′>@holy0201</a>) on <a href=’http://codepen.io’>CodePen</a>.[/codepen_embed]
スクロールするとサイドバーのウィジェットが追尾してくるのが確認できると思います。
.main {
flex: 0 0 66.6666%;
padding: 1rem;
height: 1000px;
margin-right: 2rem;
background: #fafafa;
}
.sidebar {
display: flex;
flex: 0 0 33.3333%;
background: white;
&__inner {
position: sticky;
top: 30px;
flex: 0 0 100%;
align-self: flex-start;
}
&__widget {
background: skyblue;
height: 250px;
padding: 1rem;
}
}
サイドバーのラッパーに position: sticky
を指定しています。ぴったりくっつかれるとダサいので、top: 30px
でやや余白を設けています。しきい値となる top, right, bottom, left
の初期値は auto
なので、sticky を利用するときには何らかの値を指定する必要があります。
また、スティッキーしたい要素の高さが親要素と同じだと意味が無いです。上のコードではラッパーに align-self: flex-start
を指定して Flex アイテムの高さをコンテンツに合わしています。
下に固定する
続きまして、サイドバーが長めのサイトで嬉しい、下にスティッキーするタイプです。
[codepen_embed height=”432″ theme_id=”light” slug_hash=”xgNBLK” default_tab=”result” user=”holy0201″]See the Pen <a href=’http://codepen.io/holy0201/pen/xgNBLK/’>position: sticky; Sticky sidebar(bottom)</a> by holy0201 (<a href=’http://codepen.io/holy0201′>@holy0201</a>) on <a href=’http://codepen.io’>CodePen</a>.[/codepen_embed]
&__inner {
position: sticky;
bottom: 30px;
min-height: calc(100vh - 60px);
flex: 0 0 100%;
@supports (position: sticky) {
align-self: flex-end;
}
}
align-self: flex-end
で要素を下揃えにし、bottom: 30px
で下に固定しています。ただ、未対応の Edge と IE で下揃えになっていると困るので、@supports を使って position: sticky
に対応している場合に限定しています。
また、これだとサイドバーの高さがビューポート未満の場合に下に固定されてダサいので、 min-height: calc(100vh - 60px)
で高さを持たせて、上に固定されている(ように見える)ようにしています。
ただ、これだと見た目上完全に下までスティッキーしないので、完璧ではないですね。悔C!
一部の要素だけ固定する
よく知らないのでアレですが、AdSense 広告は追尾させちゃダメらしいですね。というわけで、そういうときに使える、一部のウィジェットだけ追尾させるやつです。目次とかにも使えるね。
[codepen_embed height=”432″ theme_id=”light” slug_hash=”WRBWbL” default_tab=”result” user=”holy0201″]See the Pen <a href=’http://codepen.io/holy0201/pen/WRBWbL/’>position: sticky; Sticky sidebar(with fixed)</a> by holy0201 (<a href=’http://codepen.io/holy0201′>@holy0201</a>) on <a href=’http://codepen.io’>CodePen</a>.[/codepen_embed]
特筆することもなくシンプルです。スティッキーさせるラッパーの外にウィジェットを置いています。
まとめ
JavaScript でやるよりも描画が滑らかでパフォーマンス的にも良い(計測とかしてないけどおそらく) position: sticky。今回はサイドバーを扱いましたが、ほかにもいろいろな場面で利用できると思います。
また新たなバリエーションを思いついたら書き足していきます。といいつつしないんだろうな!