スクロールに応じてサイドバーを固定する2つの方法【CSS・jQuery】

実装イメージ

CSSを使うやり方

<div class="flex">
	<main></main>
	<aside>
		<div class="fix"></div>
	</aside>
</div>
.flex {
	display: flex;
}

.fix {
	position: sticky;
	top: 20px;
}

サイドバーの中の固定したい要素にposition: sticky;を指定するだけ!

top: 〇〇px;で固定する位置を指定します。

注意点

親要素、先祖要素のoverflowにvisible(初期値)以外の値が指定されているときは固定されません。

特に、mainとasideをfloatさせて、親要素にoverflow: hidden;を指定しているような場合ですね。

こういった場合はfloatを使うのではなく、display: flex;で横並びにしましょう。

jQueryを使うやり方

<div class="flex">
	<main></main>
	<aside>
		<div class="fix"></div>
	</aside>
</div>
.flex {
	display: flex;
}

aside {
	position: relative;
}

asideにposition: relative;を指定しておきます。

$(window).load(function() {
	if ($(".fix").length) { // .fixが存在するときのみ実行
		var fix = $(".fix"),
			fo = fix.offset().top,
			fh = fix.height(),
			aside = $("aside"),
			aw = aside.width(),
			ao = aside.offset().top,
			ah = aside.height();
		$(window).on("scroll", function() {
			var value = $(this).scrollTop();
			if (value > ao + ah - fh) { // topやbottomの値に合わせて調整
				fix.css({"position":"absolute", "width":aw, "top":"auto", "bottom":0});
			} else if (value > fo) { // topやbottomの値に合わせて調整
				fix.css({"position":"fixed", "width":aw, "bottom":"auto", "top":0});
			} else {
				fix.css("position", "static");
			}
		});
	}
});

value > の右側の値は切り替えの目安となるスクロール量で、topやbottomのほか、.fixのpaddingやmargin、asideのpaddingによって変わってくるので、微調整してください。