最初に
こんなレイアウトで、サイドメニューとメインコンテンツをそれぞれスクロールできるようにしたかった。
よく見るレイアウトなんだけど、
全然思い通りにコーディングできず苦労したのでメモしておきます。
コード
前提
reset.CSS仕込んでます
HTML
<body>
<header>
<!--任意のヘッダーコンテンツ-->
</header>
<div class="main">
<div class="main-contents">
<aside class="sidebar">
<!--任意のサイドメニューコンテンツ-->
</aside>
<div class="main-contents-body">
<!--任意のメインコンテンツ-->
</div>
</div>
</div>
</body>
CSS
body{
font-size: 1.4rem;
height: 100%;
width: 100%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 60px 1fr;
}
/* header */
header{
position: sticky;
top: 0;
height: 60px;
background-color: #eee;
}
/* main */
.main{
grid-column: 1 / 2;
grid-row: 2 / 3;
width: 100%;
height: calc(100vh - 60px);
background: pink;
}
.main-contents{
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 1fr;
align-items: flex-start;
margin: 0 auto;
max-width: 1200px;
height: 100%;
background: #fff;
}
.sidebar{
grid-column: 1 / 2;
grid-row: 1 / 2;
position: sticky;
overflow-y: auto;
height: calc(100vh - 60px);
box-sizing: border-box;
background: hotpink;
}
.main-contents-body{
grid-column: 2 / 3;
grid-row: 1 / 2;
height: calc(100vh - 60px);
overflow-y: auto;
}
解説
display: grid;を使用して要素を分割する
3つの入れ子構造にする
本来ならbody
に設定した1つのgridで事足りそうですが、
Bをmax-width: 1200px
にするためには入れ子の構造が必要になりました。
- ヘッダーと本体を分ける(gridレイアウト)
- 本体の中に、サイドメニューとメインコンテンツが入るボックスを中央に配置する(
margin: 0 auto;
) - 中央のボックスで、サイドメニューとメインコンテンツを分ける(gridレイアウト)
サイドメニューとメインコンテンツをそれぞれスクロールさせる
両方にheightを設定する
一件無駄に見えますが、これをしないとoverflow-y: auto;
が利きません。
ヘッダー下のサイズで指定したものと同じ高さにしてあげてください。
実践した感想と補足
普段はディレクター職をやっているため、久々にHTML/CSSに触れた者です。
今までJavaScriptにて処理していたものが、CSSで簡単に書ける時代になってきていますね。
想像以上にできることが多くなっていて、驚きました。
おそらくショートハンドなど活用して、もっとスマートに書けると思うので、
よりよい書き方がありましたらご教授いただけますと幸いです。
更新履歴
- 2019/10/16
- 初出
- 2019/10/17
-
<body>
関連の記述もれを追加
-