ホームページは、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は便利ですが、文法にうるさいです。
次の場合は動作しないので注意が必要です。
- 親要素に「overflow:hidden;」を指定している
- align-items: stretch;(デフォルト)になっている
動かない理由はほかにもありますが、大きくはこの2つです。
position指定は、もともと癖が強いので、使い場合には文法をよく確認する必要があります。
まずカラム分けは、float指定からflex指定に変えることこちからが大事なんだと気づきました。