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

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

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

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

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

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

サンプルはこちらです。

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

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

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

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

基本構成

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

<body><article><main></main><divid="side"></div></article></body>Code language:HTML, XML(xml)

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

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

#main
{
	width: 76%;
}

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

Code language:CSS(css)

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

全体枠(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><metacharset="shift_jis"><title></title><metaname="viewport"content="width=device-width, initial-scale=1"><styletype="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;
}


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

#sidesection
{
	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;
}

articlesection
{
	margin-bottom: 10px;
}

}


</style></head><body><header></header><article><divid="main"><section>セクション01</section><section>セクション02</section><section>セクション03</section><section>セクション04</section><section>セクション05</section></div><divid="side"><section><br></section><section></section><section></section><section></section></div></article><footer>フッター部</footer></body></html>Code language:HTML, XML(xml)

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

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

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

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

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

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

下固定にする方法

下固定にするには、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><metacharset="shift_jis"><title></title><metaname="viewport"content="width=device-width, initial-scale=1"><styletype="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;
}

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

#sidesection
{
	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;
}

articlesection
{
	margin-bottom: 10px;
}

}


</style></head><body><header></header><article><divid="main"><section>セクション01</section><section>セクション02</section><section>セクション03</section><section>セクション04</section><section>セクション05</section></div><divid="side"><section></section><section></section><section></section><section><br></section></div></article><footer>フッター部</footer></body></html>Code language:HTML, XML(xml)

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

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

  • 親要素に「overflow:hidden;」を指定している
  • align-items: stretch;(デフォルト)になっている

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

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

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております