position:sticky でサイドバーを追従させる

サイドバーをスクロールに合わせて追従させる際、position:sticky で実装しようとして少し迷う点があったので、実装方法についてメモ。

サンプルコード

例として、以下のようなシンプルなHTMLで実装してみます。

1
2
3
4
5
6
7
8
<div class="content">
    <div class="main">
        <p>コンテンツサンプル</p>
        〜 略 〜
        <p>コンテンツサンプル</p>
    </div>
    <div class="sub">サイドバー</div>
</div>

display: flex でサイドバーを配置して、.subにposition: sticky を設定します。

1
2
3
4
5
6
7
.content {
    display: flex;
}
.sub {
    position: sticky;
    top: 0;
}

これで問題ないかと思ったのですが、追従されませんでした。
うまくいかなかった場合のデモページ

追従されない原因は各要素に背景色をつけるとわかりやすいですが、.subの高さが親要素の.contentと同じだけ引き伸ばされているためです。

1
2
3
4
5
6
7
8
9
10
11
12
.content {
    display: flex;
    background: red;
}
.main {
    background: blue;
}
.sub {
    position: sticky;
    top: 0;
    background: green;
}

うまくいかなかった場合のデモページ2

align-items: flex-start を設定して、親要素と同じだけ高さを引き伸ばさないようにすることで解消できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
.content {
    display: flex;
    align-items: flex-start;
    background: red;
}
.main {
    background: blue;
}
.sub {
    position: sticky;
    top: 0;
    background: green;
}

サイドバーを追従させるデモページ

別の方法として、.sub 内にインナー要素を追加して、その要素に対してposition:sticky を設定するでもよさそうです。

1
2
3
4
5
6
7
8
9
10
<div class="content">
    <div class="main">
        <p>コンテンツサンプル</p>
        〜 略 〜
        <p>コンテンツサンプル</p>
    </div>
    <div class="sub">
        <div class="sub_inner">サイドバー</div>
    </div>
</div>

.sub_inner に対してposition: sticky の設定を行います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.content {
    display: flex;
    background: red;
}
.main {
    background: blue;
}
.sub {
    background: green;
}
.sub_inner {
    position: sticky;
    top: 0;
    background: gold;
}

サイドバーを追従させるデモページ2

関連記事

コメントを残す

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

CAPTCHA


コメントが承認されるまで時間がかかります。

2025年3月
 1
2345678
9101112131415
16171819202122
23242526272829
3031