今ならまだ間に合う! CSSのposition要素の新刺客 position: sticky; を使おう!


position: sticky;を使用するにあたり軽くハテナ???となったのでその時のメモです。
少しでも同じ思いをする人が減りますように・・・
stickyって?
position: sticky;
はpositionプロパティに追加された一番新しい要素になります。
一番新しいといってもCSSの仕様で採用されたのは2017年になります。
ただその頃は多くのウェブブラウザがこのプロパティをサポートしていなかったのであまり使われていませんでした。
しかし時は流れ・・・
2023年現在、

- ・新しいバージョンの主要なウェブブラウザ(Google Chrome、Mozilla Firefox、Microsoft Edge、Safariなど)で使えるようになった。
- ・2023年IE11のサポートが切れた。
上記の理由から問題なく使用できる環境が整っています。
stickyって何が出来るの?
出来ることの説明の前にstickyって他のposition要素に比べて意味が分かりにくいなぁと個人的に感じます。
下記がposition要素の意味一覧になります。
- static
- 「静的」
- relative
- 「相対的」
- absoulute
- 「絶対的」
- fixed
- 「固定」
- sticky
- 「接着性があり、くっつきやすい」「ネバネバする」「ベタつく」
急にかなりの変化球。。。
「接着性があり、くっつきやすい」「ネバネバする」「ベタつく」ということからなんとなく吸着するようなイメージですね。。
position: sticky;
で出来ることはposition: sticky;
に設定された要素の親要素が指定された位置までスクロールされると、画面の上部や下部、または指定された位置に固定させることができます。
これってちょっと前までは
- 1.JavaScriptのスクロールイベントを取得
- 2.指定した位置までスクロールする
- 3.JavaScriptでbodyにクラスなどを付加して固定したい要素をposition: fixed;に変更する
ということをJavaScriptを駆使して実装していました。
それがJavaScriptを使わなくてもある位置にスクロール(ビューポート)が到達した時にposition: fixed;的な動作をさせることをなんとCSSのみで実装可能になってしまうのです。
個人的にスクロールによりposition: fixed;
のON,OFF版なのかなと思っております。
position: sticky;
がよく使われるのは
- 1.ヘッダー
- 2.フッター
- 3.一覧ページや詳細ページでのサイドバーなど
になります。
百聞は一見にしかずということで下記一覧ページのサイドバーにposition: sticky;
を実装したサンプルとなります。
サンプル
サイドバーがネバネバしません。。
サイドバーがネバネバします。
stickyを設定する要素を一つ子要素にすることにより固定したい要素を選べるようになります。
stickyの実装
stickyを実装するにあたりスティッキーアイテムとスティッキーコンテナが必要になります。
今までのpositionプロパティはで単独の指定で問題なかったので
やはりposition: sticky;
・・・ 只者ではないです・・・
スティッキーアイテム
スティッキーアイテムとはスクロール(ビューポート)が到達した時に位置を固定させたいposition: sticky;
を指定した要素になります。

スティッキーコンテナ
スティッキーコンテナはスティッキーアイテムをラップする親要素になります。

スティッキーコンテナの位置までスクロールされると、スティッキーアイテムが画面の上部や下部、指定された位置に固定されます。
とても便利ですね。
stickyのはまりポイント
position: sticky;
を使ってサイドバーを接着性がありでネバネバさせてやろうと試みたのですがうまくいきませんでした。。。
いくつか実装にあたりルールが存在します。
これを一つでも破ると正しくネバネバしてくれません(T_T)。
1.固定する方向と値を必ず指定する
top
、bottom
などの方向と0
や10px
などの値は必ず指定しましょう
CSS
コピー
.sticky-item {
position: sticky;
top: 0; /* ← 必ず必要になります */
}
2.親要素のいずれかに overflow: hidden; が設定されている。
親要素のいずれかとはhtml
やbody
も含みます。.wrap
(任意)など親要素全てになります。
一つでも設定しているとその時点でstickyは無効になります。
一からコーディングする場合は意識してコーディングできますが、自分が作成したサイトではなくサイトの修正時などに後からposition: sticky;
をつけることになるとoverflow: hidden;
も必要な場合もあるので要検証となるので「簡単にできますよ」とは提案せずに注意したほうがよさそうです。
CSS
コピー
親要素 {
oveflow: hidden;/* ← stickyが無効になります。 */
}
3.スクロール可能な領域がない
今いちピントこないのですがコンテンツ部分とサイド部分の高さが同じならスクロール可能な領域がないということになります。
下図のように左のコンテンツ部分と右のstickyを指定する部分が同じ高さならスクロール可能な領域がない状態になってしまいます。
左右横並びのレイアウトは昔はboxにfloatをかけてレイアウトしていたのですが最近はdisplay: flex;でレイアウトしているので注意が必要です。
display: flex;
の性質上、デフォルトで高さを揃えてしまいます。

display: flex;時の対応策として二つあります。
スティッキーコンテナにalign-items: flex-start;を追加する
まず一つ目はalign-items: flex-start;
を追加して高さを揃えないようにします。
HTML
コピー
<div class="container-sticky">
<main class="contents">
<p class="contents-txt">
ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>
ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>
</p>
</main>
<aside class="sticky-item">
<p class="sticky-item__txt">スティッキーアイテム</p>
</aside>
</div>
CSS
コピー
.container-sticky {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start; /* ← この一行を追加する */
width: 100%;
max-width: 1280px; /* 任意のサイズ */
margin: 0 auto;
}
.contents {
width: 60%;
}
.sticky-item {
width: 35%;
position: sticky;
top: 0;
}
stickyを設定する要素を一つ子要素にする
次に2つ目はalign-items: flex-start;
を追加するのではなく追従させたい子要素を一つ作成してその要素にstickyを設定させます。

こちらの方が色々なパターンに柔軟に対応できそうなのでこの方法がベストかと思われます。
HTML
コピー
<div class="container-sticky">
<main class="contents">
<p class="contents-txt">
ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>
ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>ここが一覧ページや詳細ページのコンテンツになります。<br>
</p>
</main>
<aside class="container-aside">
<div class="sticky-item">
<p class="sticky-item__txt">スティッキーアイテム</p>
</div>
</aside>
</div>
CSS
コピー
.container-sticky {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
/*align-items: flex-start;*/ /* ← この一行は追加しない */
width: 100%;
max-width: 1280px; /* 任意のサイズ */
margin: 0 auto;
}
.contents {
width: 60%;
}
.container-aside {
width: 35%;
/* position: sticky; */ /* ← ここでstickyしない */
}
.sticky-item {
position: sticky; /* ← 子要素でstickyする */
top: 0;
}
記事を読んでからのサンプル
サイドバーがネバネバしません。。
サイドバーがネバネバします。
stickyを設定する要素を一つ子要素にすることにより固定したい要素を選べるようになります。
まとめ
ルールさえ理解していればJavaScriptを使わなくてもスクロールに合わせて追従コンテンツを簡単に作成できるので積極的に使用していきたいですね。
ただ一からサイトを構築するのではなく既存サイトにsticky
を入れるのはハマる可能性もあるので「あ。stickyあるんで楽勝すよ!5秒で実装できます!」などは言わないようにしましょう。
いやー。
既存サイトの修正でスクロールに合わせて追従コンテンツを実装してくれと頼まれたのだが「あ。stickyあるんで楽勝すよ!5秒で実装できます!いつもお世話になっているのでサービスで大丈夫!」って言ってやったわい。

・・・
師匠・・・。ハマるかもしれませんよ・・・
・・・
ん????
・・・
・・・