ブログ、メディア、管理画面では、メインコンテンツとサイドバーを並べる2カラムレイアウトがよく使われます。
この記事では、CSSで作るサイドバー付き2カラムレイアウトを20パターンに分けて紹介します。Grid、flex、左サイドバー、stickyサイドバー、スマホ1列、崩れ対策まで、コピーして使いやすい形にまとめます。
1. Gridで作る基本の2カラム
メインは可変、サイドバーは固定幅にする定番の形です。
<div class="layout-two-column">
<main>メインコンテンツ</main>
<aside>サイドバー</aside>
</div>
.layout-two-column {
display: grid;
gap: 32px;
}
@media (min-width: 960px) {
.layout-two-column {
grid-template-columns: minmax(0, 1fr) 300px;
}
}
スマホでは1列、PCでは2カラムになります。
2. 左サイドバーの2カラム
サイドバーを左に置きたい場合は、列の順番を入れ替えます。
<div class="layout-left-sidebar">
<aside>サイドバー</aside>
<main>メインコンテンツ</main>
</div>
.layout-left-sidebar {
display: grid;
gap: 32px;
}
@media (min-width: 960px) {
.layout-left-sidebar {
grid-template-columns: 280px minmax(0, 1fr);
}
}
HTMLの順番も左サイドバー、メインの順にすると理解しやすいです。
3. flexで作る2カラム
flexでもメインとサイドバーを横並びにできます。
<div class="layout-flex-column">
<main>メインコンテンツ</main>
<aside>サイドバー</aside>
</div>
.layout-flex-column {
display: flex;
gap: 32px;
}
.layout-flex-column main {
flex: 1;
min-width: 0;
}
.layout-flex-column aside {
flex: 0 0 300px;
}
@media (max-width: 959px) {
.layout-flex-column {
flex-direction: column;
}
}
flexでは、メイン側の min-width: 0; が崩れ対策として重要です。
4. 70%と30%の比率で分ける
サイドバー幅を固定せず、割合で分ける方法です。
.layout-ratio {
display: grid;
gap: 32px;
}
@media (min-width: 960px) {
.layout-ratio {
grid-template-columns: 7fr 3fr;
}
}
比率指定は画面幅に応じて両方が伸びるため、固定幅より柔らかいレイアウトになります。
5. サイドバー幅をclampで可変にする
サイドバーを画面幅に合わせて少しだけ可変にしたい場合の例です。
.layout-clamp-sidebar {
display: grid;
gap: 32px;
}
@media (min-width: 960px) {
.layout-clamp-sidebar {
grid-template-columns: minmax(0, 1fr) clamp(240px, 28vw, 340px);
}
}
clamp() を使うと、最小幅・可変幅・最大幅をまとめて指定できます。
6. 最大幅つきの2カラム
画面いっぱいに広げず、中央に最大幅を持たせる形です。
<div class="layout-container">
<main>メイン</main>
<aside>サイドバー</aside>
</div>
.layout-container {
display: grid;
gap: 32px;
max-width: 1120px;
margin: 0 auto;
padding: 0 20px;
}
@media (min-width: 960px) {
.layout-container {
grid-template-columns: minmax(0, 1fr) 300px;
}
}
実サイトでは、最大幅と左右余白をセットで考えると安定します。
7. stickyサイドバー
目次やプロフィールをスクロールに追従させたい場合は、position: sticky; を使います。
<aside class="sidebar">
<div class="sidebar-sticky">目次</div>
</aside>
.sidebar-sticky {
position: sticky;
top: 24px;
}
親要素に overflow: hidden; などがあると、stickyが効かないことがあります。
8. 固定ヘッダーがあるときのsticky位置
固定ヘッダーがある場合は、ヘッダーの高さ分だけ top を空けます。
.sidebar-sticky-with-header {
position: sticky;
top: 88px;
}
固定ヘッダーと重ならないように、top を調整します。
9. サイドバーをスマホでは下に回す
HTMLでメインを先に書いておくと、スマホで本文の下にサイドバーが来ます。
<div class="layout-sidebar-bottom">
<main>本文</main>
<aside>関連記事</aside>
</div>
.layout-sidebar-bottom {
display: grid;
gap: 32px;
}
@media (min-width: 960px) {
.layout-sidebar-bottom {
grid-template-columns: minmax(0, 1fr) 300px;
}
}
本文を優先して読ませたいブログでは、この順番が扱いやすいです。
10. サイドバーをスマホでは上に出す
検索や絞り込みを先に使わせたい場合は、スマホでサイドバーを上に出します。
<div class="layout-sidebar-top">
<main>商品一覧</main>
<aside>絞り込み</aside>
</div>
.layout-sidebar-top {
display: grid;
gap: 24px;
}
.layout-sidebar-top aside {
order: -1;
}
@media (min-width: 960px) {
.layout-sidebar-top {
grid-template-columns: minmax(0, 1fr) 300px;
}
.layout-sidebar-top aside {
order: 0;
}
}
絞り込みUIでは、スマホで先に表示した方が使いやすい場合があります。
11. サイドバー内をカードで分ける
プロフィール、カテゴリ、人気記事などをカードとして並べる例です。
<aside class="sidebar-cards">
<section>プロフィール</section>
<section>カテゴリ</section>
<section>人気記事</section>
</aside>
.sidebar-cards {
display: grid;
gap: 16px;
}
.sidebar-cards section {
padding: 18px;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
カード単体の装飾は、CSSカードデザイン集 に分けるとよいです。
12. 目次サイドバー
記事ページで使いやすい、目次用サイドバーの例です。
<aside class="toc-sidebar">
<p>目次</p>
<a href="#sec1">基本</a>
<a href="#sec2">応用</a>
<a href="#sec3">まとめ</a>
</aside>
.toc-sidebar {
display: grid;
gap: 10px;
padding: 18px;
background: #f8fafc;
border-radius: 8px;
}
.toc-sidebar p {
margin: 0;
font-weight: 700;
}
.toc-sidebar a {
color: #475569;
text-decoration: none;
}
リンク数が多い場合は、余白を詰めすぎないようにします。
13. 広告枠つきサイドバー
広告やバナー枠を置く場合は、枠のサイズを安定させます。
<aside class="ad-sidebar">
<div class="ad-box">広告枠</div>
</aside>
.ad-box {
display: grid;
place-items: center;
min-height: 250px;
color: #64748b;
background: #f1f5f9;
border: 1px dashed #cbd5e1;
border-radius: 8px;
}
広告枠は高さが急に変わるとレイアウトが揺れるため、最小高さを決めておくと安心です。
14. メインが狭くなりすぎない2カラム
サイドバーが広すぎると本文が読みにくくなるため、メイン側に最小幅を意識します。
.layout-readable {
display: grid;
gap: 32px;
}
@media (min-width: 1040px) {
.layout-readable {
grid-template-columns: minmax(620px, 1fr) 280px;
}
}
本文が主役のページでは、サイドバーよりメインの読みやすさを優先します。
15. 画像や長いURLではみ出すときの対策
メインカラム内の画像や長い文字が原因で、2カラムが崩れることがあります。
.layout-overflow-fix {
display: grid;
gap: 32px;
grid-template-columns: minmax(0, 1fr) 300px;
}
.layout-overflow-fix main {
min-width: 0;
}
.layout-overflow-fix img {
max-width: 100%;
height: auto;
}
.layout-overflow-fix p {
overflow-wrap: anywhere;
}
minmax(0, 1fr) と min-width: 0; が効きます。
16. サイドバーを非表示にするブレイクポイント
スマホではサイドバーを非表示にする設計もあります。
.layout-hide-sidebar {
display: block;
}
.layout-hide-sidebar aside {
display: none;
}
@media (min-width: 960px) {
.layout-hide-sidebar {
display: grid;
grid-template-columns: minmax(0, 1fr) 300px;
gap: 32px;
}
.layout-hide-sidebar aside {
display: block;
}
}
重要な情報をサイドバーだけに置くと、スマホで見えなくなるため注意します。
17. サイドバーを横スクロール領域にする
タグやカテゴリだけなら、スマホでは横スクロールにする方法もあります。
.mobile-filter-list {
display: flex;
gap: 8px;
overflow-x: auto;
padding-bottom: 8px;
white-space: nowrap;
}
.mobile-filter-list a {
flex: 0 0 auto;
padding: 8px 12px;
color: #334155;
text-decoration: none;
background: #f1f5f9;
border-radius: 9999px;
}
カテゴリタグの見た目は、CSSバッジ・ラベル・タグデザイン集 と相性がよいです。
18. 3カラムに拡張できるGrid
将来、左右にサイドバーを置く可能性がある場合の土台です。
<div class="layout-three-ready">
<aside>左</aside>
<main>メイン</main>
<aside>右</aside>
</div>
.layout-three-ready {
display: grid;
gap: 24px;
}
@media (min-width: 1120px) {
.layout-three-ready {
grid-template-columns: 220px minmax(0, 1fr) 280px;
}
}
この記事の主役は2カラムですが、Gridなら3カラムへの拡張もしやすいです。
19. CSS変数で幅と余白を管理する
複数ページで使い回すなら、サイドバー幅や余白を変数にします。
.layout-variable {
--sidebar-width: 300px;
--layout-gap: 32px;
display: grid;
gap: var(--layout-gap);
}
@media (min-width: 960px) {
.layout-variable {
grid-template-columns: minmax(0, 1fr) var(--sidebar-width);
}
}
ページごとに幅を変える場合も、変数なら調整しやすくなります。
20. 2カラムの最小テンプレート
最後に、まずコピーするならこの形です。
<div class="layout-template">
<main>メインコンテンツ</main>
<aside>サイドバー</aside>
</div>
.layout-template {
display: grid;
gap: 32px;
max-width: 1120px;
margin: 0 auto;
padding: 0 20px;
}
@media (min-width: 960px) {
.layout-template {
grid-template-columns: minmax(0, 1fr) 300px;
}
}
スマホ1列、PC2カラム、最大幅ありの実用的なテンプレートです。
2カラムレイアウトが崩れる原因
- スマホでも2カラムのままにしている
- サイドバー幅が広すぎて、メインが狭くなっている
- メインカラムに長いURLや大きな画像が入っている
minmax(0, 1fr)やmin-width: 0;がない- 余白を含めた合計幅が親要素を超えている
まとめ
サイドバー付き2カラムは、スマホでは1列、PCではメインとサイドバーに分けるのが基本です。
Gridなら grid-template-columns: minmax(0, 1fr) 300px;、flexならメインに min-width: 0; を入れると崩れにくくなります。
Gridの詳しい使い方は CSS Gridの使い方、flexの詳しい使い方は CSS flexの使い方 に分けると記事同士の役割が明確になります。