今回は、CSSだけでサイドバーを固定する方法を紹介します。
コンテンツをスクロールすると、サイドバーの一部が途中から追従する動きは、ブログなど2カラムのサイトではよく使われています。
頻繁に使われるので、実装方法を覚えてきましょう。
完成形
実際にできあがるのは以下のリンク先にあるようなサイドバーです。
サイドバーの下部にあるエリアが、スクロールに追従するようになります。
昔はJavaScriptを駆使して実装していましたが、今ではCSSだけでできるようになりました。
デモのコード
HTML
bodyやヘッダー、フッターのHTMLは省略します。
<div class="wrapper">
<main class="main"></main>
<aside class="sidebar">
<div class="widget"></div>
<div class="widget widget--sticky"></div>
</aside>
</div>
以下のCSSで、.widget--sticky
のエリアが固定されるように指定します。
CSS
デモでは分かりやすいように、各要素にグレーの色を付けてますが実際には不要なので、省略しています。
.wrapper {
width: 94%;
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
}
.main {
width: calc(100% - 300px);
}
.sidebar {
width: 280px;
}
.widget + .widget {
margin-top: 20px;
}
.widget--sticky {
position: sticky;
top: 20px; /* スクロール時にビューポートの20px位置に達すると固定 */
}
解説
このCSSのポイントは2つです。
実装のポイント
- スクロール追従させたい要素にposition: sticky
- サイドバーの親要素はdisplay: flex
スクロール追従させたい要素にposition: stickyを入れる
追従させたい要素にposition: sticky
を指定します。
top
プロパティでスクロール時にどこで固定するかを指定します。
ここで固定する位置とは、指定した要素(.widget--sticky
クラス)が、スクロール時に「画面の見える範囲のどこに固定するか」を決めるものです。
例えば top: 0px;
にすると、その要素が「画面の一番上」に到達した時点で固定されます。
デモでは top: 20px;
なので、「画面の上から 20px の位置」にその要素が達すると固定されます。
.widget--sticky {
position: sticky;
top: 20px; /* スクロール時にビューポートの20px位置に達すると固定 */
}
それではどこまでスクロールすると、position: siticky; を指定した要素は固定解除されるのでしょうか?
それは、その要素の親要素の範囲を超えると(下端に到達すると)解除されます。
position: siticky; は、その親要素の範囲の中でのみ固定されるようになっています。
デモでは、position: stickyを指定した要素<div class="widget widget--sticky">
(.widget–sticky クラス)の親要素は<div class="wrapper">
(.wrapper クラス)になっています。
この親要素<div class="wrapper">
の中でのみ固定されています。
サイドバーの親要素はdisplay: flex
要素を横並びにする方法はいくつかありますが、以前ならfloat
が使われていましたが、現在では主にdisplay: flex
が使われます。
display: flex
で横並びにすると、それぞれの要素が同じ高さになります。

float
とclearfixを使う方法だと、それぞれの要素の高さが異なります。

float
を使うと、サイドバー内にスペースがない状態になってしまいます。
これでは、スクロール追従させたい要素が動かなくなってしまうのです。
ですので、サイドバーのスクロール追従をする場合は、2カラムのレイアウトをflexboxで組んでください。
今時2カラムのレイアウトでfloatを使う人はほとんどいないと思いますが、一応頭に入れておいてください。
注意点
このCSSには注意点があります。
それは、サイドバーの親要素でoverflow:hidden
を使ってはいけないという点です。
例えば、body要素やwrapperクラスにoverflow:hidden
が指定されていると、サイドバーが固定されなくなります。
/* 固定されない例 */
body {
overflow: hidden;
}
.widget--sticky {
position: sticky;
top: 20px;
}
topやbottomを指定している場合、親要素にoverflow-x: hidden;
なら問題なく動作します。
/* 問題なく固定される例 */
body {
overflow-x: hidden;
}
.widget--sticky {
position: sticky;
top: 20px;
}
bodyで横にはみ出るのを防ぎたい場合、overflow
ではなくoverflow-x
を使いましょう。
stickyの対応ブラウザ
position: sticky
は現状、全てのモダンブラウザでサポートされています。
IEがサポート終了したので遠慮なく使って大丈夫です。
なお、今回ご紹介した position: sticky; 以外のオプションについても下記で解説しています。
よろしければご確認くださいませ。

【CSS】positionのrelative、absolute、fixed、stickyの使い…
今回は、CSSのpositionプロパティについて詳しく解説します。positionはレイアウトに必…

【HTML/CSS】横スクロールできる表(テーブル)の作り方
今回は、HTMLとCSSで横スクロールできる表の作り方を解説します。スマホ環境ですと表が入りきらない…

【CSSのみ】ページ内リンクでコンテンツを画面中央にする方法
今回は、ページ内リンクで遷移先のコンテンツを、画面中央に配置するテクニックを紹介します。JavaSc…