ホームページ制作 オフィスオバタ

スタイルシートだけで サイド部分をスクロール固定する。

ホームページは、2列構成になるケースがあります。
メインカラムと、サイドカラムです。

たいていメインカラムのほうが縦に長く、サイドカラムは上へ流れて行ってしまいます。
その場合、サイドカラムはほとんど見てもらえなくなります。

これを何とかするために、サイドカラムを位置固定する方法があります。
特定位置になったら固定し、フッターが来たら固定を解除するものです。

今まではJqueryで実装していましたが、スタイルシートだけで実現できることがわかりました。
忘備録として記録いたします。

まずはできたものがこちら

サンプルはこちらです。

右サイド部分がスタイルシートだけで固定できています。
いったいどうやっているのでしょうか?

position:sticky; を使えば簡単に実現できます。

position:は、fixed、absoluteなどを指定します。
その仲間で、stickyがあります。

意味合い的には、「特定位置になったら固定」というものです。
なんとも便利なスタイルシートです。

基本構成

基本的な構成は次のようになります。
いわゆるよくあるパターンです。

<body>
<article>

<main>
メインカラム
</main>

<div id="side">
サイド部分
</div>

</article>
</body>

基本スタイルシートはこのようになります。


article
{
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
}

#main
{
	width: 76%;
}

#side
{
	width: 20%;
	position: sticky;
	top: 20px;
}

基本これだけでサイドカラムがスクロール固定されます。

全体枠(article)は必ずflexにする

2カラム構成にする場合、「float」を使う方法がありますが、今回はNGです。
なぜならば、ちゃんと動作しなくなるためです。
サイドカラムを包括するタグには必ずflexで2カラム構成にします。

justify-content: space-between;の意味

これは、flexに対して、横位置を均等割り当てをするという意味です。
今回は、メインカラムは一番左よせ、サイドカラムは一番右よせにしたいので、「均等割り当て」で配置しています。

こちらの解説をみると、わかりやすいです。

align-items: flex-start;の意味

これは、flexに対して縦位置を上に割り当てるという意味です。
今回は、サイドカラムが画面の一番上に来たら固定するため、上位置を指定しています。

こちらの解説をみると、わかりやすいです。

サイド部分(#side)はstickyとtopを指定する

実際に固定化する部分に「sticky」を設定します。
さらに、topを数字で指定します。
topを指定しないとうまく動きません。

ちなみに、必ず0にする必要はなく、固定化する位置によって変えてOKです。

ソースはこちら


<!doctype html>
<html>
<head>
<meta charset="shift_jis">
<title>サイド固定(上固定)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<style type="text/css">
html
{
	scroll-behavior: smooth;
}

body 
{
	margin: 0px;
	padding: 0px;
	text-align: center;
}

header
{
	color: #FFF;
	background-color: #333;
	padding-top: 50px;
	padding-bottom: 50px;

}

footer
{
	color: #FFF;
	background-color: #333;
	padding-top: 100px;
	padding-bottom: 100px;
}

article
{
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	width: 1200px;
	margin-right: auto;
	margin-left: auto;
	padding-top: 30px;
	padding-bottom: 30px;
}

#main
{
	width: 860px;
}

#side
{
	width: 300px;
	position: sticky;
	top: 20px;
}


article section
{
	padding-top: 200px;
	padding-bottom: 200px;
	border: 3px solid #CCC;
	margin-bottom: 30px;
}

#side section
{
	padding-top: 100px;
	padding-bottom: 100px;
	background-color: #FFC;
}

@media screen and (max-width:767px)
{

header
{
	padding-top: 20px;
	padding-bottom: 20px;
}

article
{
	display: block;
	width: auto;
	padding-top: 20px;
	padding-right: 10px;
	padding-bottom: 10px;
	padding-left: 10px;
}

#main
{
	width: auto;
}

#side
{
	width: auto;
}

article section
{
	margin-bottom: 10px;
}

}


</style>
</head>

<body>
<header>ヘッダー部</header>

<article>

<div id="main">
<section>セクション01</section>
<section>セクション02</section>
<section>セクション03</section>
<section>セクション04</section>
<section>セクション05</section>
</div>

<div id="side">
<section>サイド部分01<br>上固定されます</section>
<section>サイド部分02</section>
<section>サイド部分03</section>
<section>サイド部分04</section>
</div>

</article>

<footer>フッター部</footer>
</body>
</html>

これってサイド部が上固定だけど、下固定にはできないのか?

サンプルは、サイド部分が上固定になっています。
ですが、下固定にしたいケースもあります。
それって実現できないのか、調べてみました。

調べてみたら、スタイルシートのオプションを変えるだけで実現できることがわかりました。

サイド部分下固定のサンプル

実際に下固定にできたものがこちらです。

右サイド部分が下固定で動きます。

下固定にする方法

下固定にするには、2カ所変更すれば実現できます。

(1)article のalign-items: flex-start;をalign-items: flex-end;にする

包括部分(article)をalign-items: flex-end;にすれば「下位置合わせ」になります。
flex-startが基準位置上に対し、flex-endは基準位置下になります。

(2)#sideのtop を削除し、bottomを追加する。

stickyを指定しているサイド部分には、スタイルシートでtopを指定します。
これを削除し、代わりにbottomを指定します。
下基準にするので、bottomです。

この2カ所変えるだけで下固定に代わります。

下固定のソースはこちら


<!doctype html>
<html>
<head>
<meta charset="shift_jis">
<title>サイド固定(下固定)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<style type="text/css">
html
{
	scroll-behavior: smooth;
}

body 
{
	margin: 0px;
	padding: 0px;
	text-align: center;
}

header
{
	color: #FFF;
	background-color: #333;
	padding-top: 50px;
	padding-bottom: 50px;

}

footer
{
	color: #FFF;
	background-color: #333;
	padding-top: 100px;
	padding-bottom: 100px;

}

article
{
	display: flex;
	justify-content: space-between;
	align-items: flex-end;
	width: 1200px;
	margin-right: auto;
	margin-left: auto;
	padding-top: 30px;
	padding-bottom: 30px;
}

#main
{
	width: 860px;
}

#side
{
	width: 300px;
	position: -webkit-sticky;
	position: sticky;
	bottom: 20px;
}

article section
{
	padding-top: 200px;
	padding-bottom: 200px;
	border: 3px solid #CCC;
	margin-bottom: 30px;
}

#side section
{
	padding-top: 100px;
	padding-bottom: 100px;
	background-color: #FFC;
}

@media screen and (max-width:767px)
{

header
{
	padding-top: 20px;
	padding-bottom: 20px;
}

article
{
	display: block;
	width: auto;
	padding-top: 20px;
	padding-right: 10px;
	padding-bottom: 10px;
	padding-left: 10px;
}

#main
{
	width: auto;
}

#side
{
	width: auto;
}

article section
{
	margin-bottom: 10px;
}

}


</style>
</head>

<body>
<header>ヘッダー部</header>

<article>

<div id="main">
<section>セクション01</section>
<section>セクション02</section>
<section>セクション03</section>
<section>セクション04</section>
<section>セクション05</section>
</div>

<div id="side">
<section>サイド部分01</section>
<section>サイド部分02</section>
<section>サイド部分03</section>
<section>サイド部分04<br>固定されます</section>
</div>

</article>

<footer>フッター部</footer>
</body>
</html>

次のような場合はちゃんと動かないので注意です。

stickyは便利ですが、文法にうるさいです。
次の場合は動作しないので注意が必要です。

動かない理由はほかにもありますが、大きくはこの2つです。
position指定は、もともと癖が強いので、使い場合には文法をよく確認する必要があります。

まずカラム分けは、float指定からflex指定に変えることこちからが大事なんだと気づきました。

モバイルバージョンを終了