1. 👋 はじめに
前回はCSSの基礎・セレクター・詳細度・カスケード・CSS変数を学びました。今回は CSSレイアウトの核心 を解説します!
「CSSレイアウトが難しい」と感じる原因の多くは、ボックスモデルとFlexbox・Gridの仕組みを理解していないからです。
今回でその謎を完全に解き明かしましょう!
この記事を読めば:
- ✅ ボックスモデルを理解できる
- ✅ Flexboxで自在にレイアウトを組める
- ✅ CSS Gridで複雑なレイアウトを作れる
- ✅ positionプロパティを使いこなせる
- ✅ レスポンシブデザインの実装方法がわかる
2. 📦 ボックスモデル
すべての要素は「箱」でできている
CSSでは、すべてのHTML要素は「箱(ボックス)」として扱われます。
この「箱」の構造を理解することがレイアウトの第一歩です。
| 部分 | 役割 | 例え |
|---|---|---|
content |
テキストや画像などの中身 | 手紙の文章 |
padding |
コンテンツと枠線の間の余白 | 封筒の内側の余白 |
border |
枠線 | 封筒の縁 |
margin |
他の要素との間の余白 | 封筒同士の隙間 |
margin・padding の書き方
/* 上下左右すべて同じ値 */
margin: 16px;
padding: 16px;
/* 上下・左右を別々に指定 */
margin: 16px 8px; /* 上下16px・左右8px */
padding: 8px 16px; /* 上下8px・左右16px */
/* 上・右・下・左(時計回り)で別々に指定 */
margin: 8px 16px 4px 12px;
/* 個別に指定 */
margin-top: 16px;
margin-right: 8px;
margin-bottom: 16px;
margin-left: 8px;
padding-top: 8px;
padding-right: 16px;
padding-bottom: 8px;
padding-left: 16px;
box-sizing:ボックスの計算方法
box-sizingは「widthとheightが何を基準に計算されるか」を指定するプロパティです。
/* ❌ content-box(デフォルト):paddingとborderが幅に追加される */
.box {
width: 200px;
padding: 20px;
border: 2px solid;
/* 実際の表示幅:200 + 20×2 + 2×2 = 244px 😱 */
}
/* ✅ border-box:paddingとborderを含めた幅になる(現代の標準) */
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 2px solid;
/* 実際の表示幅:200px(指定通り!) */
}
/* 全要素にborder-boxを適用する(現代の標準的な設定) */
*,
*::before,
*::after {
box-sizing: border-box;
}
💡 Tailwindなどのフレームワークは最初から
border-boxが設定されています。
素のCSSを書くときは必ずこのリセットを最初に書く習慣をつけましょう!
marginの相殺(マージンの折りたたみ)
/* ⚠️ 上下のmarginは相殺される! */
.box-a { margin-bottom: 32px; }
.box-b { margin-top: 16px; }
/* 実際の間隔は 32px + 16px = 48px ではなく
大きい方の 32px になる(相殺)! */
【相殺が起きる条件】
✅ 上下方向のmarginが接している場合(左右は相殺されない)
✅ 親子要素のmarginが接している場合
❌ Flexbox・Gridのアイテムでは相殺は起きない
3. 🔧 Flexbox
Flexboxとは?
Flexboxは「子要素を1方向(横または縦)に並べるレイアウト方法」です。
ナビゲーション・カードの横並び・中央揃えなど、1方向のレイアウトに最適です。
Flexboxの基本
/* 親要素に display: flex を指定するだけで子要素が横並びになる */
.container {
display: flex;
}
主軸と交差軸
flex-direction:並ぶ方向
.container {
flex-direction: row; /* 横並び・左から右(デフォルト) */
flex-direction: row-reverse; /* 横並び・右から左 */
flex-direction: column; /* 縦並び・上から下 */
flex-direction: column-reverse; /* 縦並び・下から上 */
}
justify-content:主軸方向の揃え方
.container {
justify-content: flex-start; /* 左揃え(デフォルト) */
justify-content: flex-end; /* 右揃え */
justify-content: center; /* 中央揃え */
justify-content: space-between; /* 両端に配置・均等間隔 */
justify-content: space-around; /* 均等間隔(両端にも余白) */
justify-content: space-evenly; /* すべての間隔が均等 */
}
align-items:交差軸方向の揃え方
.container {
align-items: stretch; /* 高さを揃える(デフォルト) */
align-items: flex-start; /* 上揃え */
align-items: flex-end; /* 下揃え */
align-items: center; /* 垂直中央揃え */
align-items: baseline; /* テキストのベースラインで揃える */
}
flex-wrap:折り返し
.container {
flex-wrap: nowrap; /* 折り返さない(デフォルト) */
flex-wrap: wrap; /* 幅が足りないとき折り返す */
flex-wrap: wrap-reverse; /* 逆方向に折り返す */
}
gap:要素間の隙間
.container {
gap: 16px; /* 縦横すべて16px */
gap: 16px 8px; /* 行間16px・列間8px */
row-gap: 16px; /* 行間のみ */
column-gap: 8px; /* 列間のみ */
}
子要素に使うプロパティ
.item {
/* flex-grow:余ったスペースをどれくらい取るか(比率) */
flex-grow: 0; /* デフォルト:余ったスペースを取らない */
flex-grow: 1; /* 余ったスペースを1の比率で取る */
/* flex-shrink:スペースが足りないとき縮む比率 */
flex-shrink: 1; /* デフォルト:均等に縮む */
flex-shrink: 0; /* 縮まない */
/* flex-basis:ベースとなる幅(または高さ) */
flex-basis: auto; /* デフォルト:コンテンツに応じる */
flex-basis: 200px; /* 200pxをベースにする */
/* flex:上3つのショートハンド */
flex: 0 1 auto; /* デフォルト値 */
flex: 1; /* flex-grow:1・flex-shrink:1・flex-basis:0% */
flex: 0 0 200px; /* 縮まない・200px固定 */
}
⚠️
flex: 1の展開値に注意!
flex: 1と書いたときflex-basisはautoではなく0%になります。/* flex: 1; の実際の展開値 */ flex-grow: 1; flex-shrink: 1; flex-basis: 0%; /* auto ではなく 0% がポイント! */
flex-basis: 0%になることで、コンテンツの元々の幅を無視して
完全に均等な幅 でスペースを分配できます。
「なぜかアイテムの幅が均等にならない」というときは
flex-basisの値を確認してみましょう。
/* order:表示順(小さい数が先に表示) */
order: 0; /* デフォルト */
order: -1; /* 先頭に移動 */
order: 1; /* 末尾に移動 */
/* align-self:自分だけalign-itemsを上書き */
align-self: center;
}
よくあるFlexboxのパターン
/* ① 水平・垂直の中央揃え(最も使われるパターン!) */
.center {
display: flex;
justify-content: center;
align-items: center;
}
/* ② ナビゲーションバー */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
}
/* ③ カードの横並び(折り返しあり) */
.card-list {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
/* ④ サイドバーレイアウト(サイドバー固定・メインが伸びる) */
.layout {
display: flex;
gap: 24px;
}
.sidebar { flex: 0 0 240px; } /* 240px固定・縮まない */
.main { flex: 1; } /* 残りのスペースをすべて使う */
4. 🔲 CSS Grid
CSS Gridとは?
CSS Gridは「行と列を組み合わせた2次元のレイアウト方法」です。
ダッシュボード・ギャラリー・複雑なページレイアウトに最適です。
Gridの基本
.container {
display: grid;
/* 列の定義 */
grid-template-columns: 200px 1fr 1fr;
/* → 1列目:200px固定・2列目と3列目:残りを均等に2分割 */
grid-template-columns: repeat(3, 1fr);
/* → 3列均等(1fr = 1fraction = 均等に分けた1つ分) */
/* 行の定義 */
grid-template-rows: 60px 1fr 60px;
/* → ヘッダー:60px・メイン:残り全部・フッター:60px */
/* 要素間の隙間 */
gap: 16px;
column-gap: 24px; /* 列間のみ */
row-gap: 16px; /* 行間のみ */
}
fr(フラクション)とは?
fr = fraction(分数・割り合い)
grid-template-columns: 1fr 2fr 1fr の場合:
全体を 1+2+1 = 4 に分割
1列目 → 全体の 1/4
2列目 → 全体の 2/4(半分)
3列目 → 全体の 1/4
┌───────┬──────────────┬───────┐
│ 1fr │ 2fr │ 1fr │
└───────┴──────────────┴───────┘
repeat():繰り返しの定義
/* repeat(繰り返し回数, 値) */
grid-template-columns: repeat(4, 1fr);
/* → 1fr 1fr 1fr 1fr と同じ(4列均等) */
/* auto-fill:コンテナの幅に応じて列数を自動調整 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* → 最小200px・最大1frのカラムを自動で並べる(レスポンシブグリッドに最適!) */
/* auto-fit:auto-fillと似ているが、空の列を折りたたむ */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
💡
auto-fillとauto-fitの違い:アイテムが少ないときの挙動コンテナの幅が800px・最小列幅200px(最大4列入る)の場合 アイテムが2つしかないとき: auto-fill: [アイテム①] [アイテム②] [空の列] [空の列] → 空の列スペースを維持する auto-fit: [ アイテム① ] [ アイテム② ] → 空の列を潰してアイテムが画面いっぱいに広がる
auto-fill auto-fit 空の列の扱い 維持する 潰す 少ないアイテム 左寄せになる 均等に広がる 向いている場面 後からアイテムが増える想定 アイテム数が少ない画面
子要素の配置
.item {
/* grid-column:何列目から何列目まで占めるか */
grid-column: 1 / 3; /* 1列目から3列目の手前まで(2列分) */
grid-column: 1 / -1; /* 最初から最後まで(全列幅) */
grid-column: span 2; /* 2列分を占める */
/* grid-row:何行目から何行目まで占めるか */
grid-row: 1 / 3; /* 1行目から3行目の手前まで(2行分) */
grid-row: span 2; /* 2行分を占める */
}
grid-template-areas:エリア名でレイアウトを定義
.container {
display: grid;
grid-template-columns: 240px 1fr;
grid-template-rows: 60px 1fr 60px;
grid-template-areas:
"header header" /* 1行目:headerが2列全体 */
"sidebar main" /* 2行目:左にsidebar・右にmain */
"footer footer"; /* 3行目:footerが2列全体 */
gap: 16px;
min-height: 100vh;
}
/* 各要素にエリア名を割り当てる */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
<!-- HTMLはシンプルにそのまま -->
<div class="container">
<header class="header">ヘッダー</header>
<aside class="sidebar">サイドバー</aside>
<main class="main">メインコンテンツ</main>
<footer class="footer">フッター</footer>
</div>
FlexboxとGridの使い分け
| Flexbox | Grid | |
|---|---|---|
| 次元 | 1次元(横 or 縦) | 2次元(横と縦) |
| 向いている用途 | ナビバー・カード横並び・中央揃え | ダッシュボード・複雑なレイアウト |
| レイアウトの制御 | 子要素が自分のサイズを決める | 親要素がレイアウトを決める |
| 使い始めの難易度 | 低い | 中程度 |
判断のコツ:
「1方向に並べたい」 → Flexbox
例:横並びのナビメニュー・縦並びのリスト
「行と列で複雑に配置したい」 → Grid
例:ECサイトの商品一覧・ダッシュボード
「どちらでも書ける」場合は →
小さいコンポーネント内 → Flexbox
ページ全体のレイアウト → Grid
5. 📍 position プロパティ
positionとは?
positionプロパティは「要素の配置方法」を指定します。
top・right・bottom・leftプロパティと組み合わせて使います。
static(デフォルト)
.element {
position: static; /* デフォルト:通常の文書の流れに従う */
/* top・left などは効かない */
}
relative(相対配置)
.element {
position: relative;
top: 10px; /* 本来の位置から10px下にずらす */
left: 20px; /* 本来の位置から20px右にずらす */
/* ※ 元のスペースは保持される */
}
relativeのイメージ:
通常の位置: [ A ][ B ][ C ]
relative適用後:[ A ][ B(↓10px・→20px) ][ C ]
↑ 元のスペースはそのまま
absolute(絶対配置)
/* 基準となる祖先要素(position: relative等)から相対的に配置 */
.parent {
position: relative; /* 基準点になる */
}
.child {
position: absolute;
top: 0;
right: 0;
/* 親要素の右上に配置される */
/* ※ 文書の流れから外れる(他の要素に影響しない) */
}
⚠️
position: absoluteの基準となる親要素に注意!
position: absoluteはposition: static以外の値(relative・absolute・fixed・sticky)を持つ
最も近い祖先要素 を基準に配置されます。親要素に
position: relativeを付け忘れると、
意図せず 画面全体(body)の右上まで飛んで行ってしまう という
初心者がよくハマるミスが起きます!/* ❌ よくあるミス:親にpositionを指定し忘れる */ .parent { } /* positionなし → static */ .badge { position: absolute; top: 0; right: 0; /* → 画面全体の右上に飛んでしまう! 😱 */ } /* ✅ 正しい使い方:基準にしたい親に必ずrelativeをセット */ .parent { position: relative; } /* ← これを忘れない! */ .badge { position: absolute; top: 0; right: 0; /* → .parentの右上に配置される ✅ */ }
absoluteのよくある使い方:
・バッジ(通知の数字)をアイコンの右上に表示
・ドロップダウンメニューを親要素の下に表示
・ツールチップ(ホバー時の説明)を要素の上に表示
.badge-wrapper {
position: relative; /* バッジの基準点 */
}
.badge {
position: absolute;
top: -8px;
right: -8px; /* 右上に表示 */
}
fixed(固定配置)
.element {
position: fixed;
top: 0;
left: 0;
width: 100%;
/* ビューポート(画面)に対して固定 */
/* スクロールしても動かない */
}
fixedのよくある使い方:
・固定ヘッダー(スクロールしても上部に固定)
・固定フッター(スクロールしても下部に固定)
・モーダルの背景オーバーレイ
・チャットの浮かせボタン
sticky(スクロール連動配置)
.element {
position: sticky;
top: 0; /* スクロールして上端に来たら固定される */
/* 通常は文書の流れに従い・指定位置に来たらfixedのように固定 */
}
stickyのよくある使い方:
・テーブルのヘッダー行(スクロールしても見出しを表示)
・セクションの見出し(目次のような挙動)
・サイドバーの追従
.table-header {
position: sticky;
top: 0;
background: white; /* 背景が透明だと下の内容が透けるので注意 */
z-index: 10;
}
z-index:重なり順
/* z-indexが大きいほど手前に表示される */
.modal-overlay {
position: fixed;
z-index: 100;
}
.modal {
position: fixed;
z-index: 101; /* overlayより手前 */
}
.tooltip {
position: absolute;
z-index: 200;
}
💡 z-indexはpositionがstatic以外の要素にしか効きません!
position: static(デフォルト)の要素に z-index を指定しても無視されます。
6. 📱 レスポンシブデザイン
レスポンシブデザインとは?
「画面サイズに応じてレイアウトが変わるデザイン」のことです。
スマホ・タブレット・PCすべてで見やすいページを1つのCSSで実現します。
メディアクエリの基本
/* min-width:この幅以上のとき適用(モバイルファースト) */
@media (min-width: 768px) {
.container {
flex-direction: row;
}
}
/* max-width:この幅以下のとき適用(デスクトップファースト) */
@media (max-width: 767px) {
.container {
flex-direction: column;
}
}
/* 範囲指定 */
@media (min-width: 768px) and (max-width: 1023px) {
/* タブレットのみ */
}
💡 モダンな書き方(Media Queries Level 4)
現代のブラウザでは比較演算子を使った直感的な記法が使えます!/* 従来の書き方 */ @media (min-width: 768px) { ... } @media (max-width: 767px) { ... } /* モダンな書き方(直感的で読みやすい!) */ @media (width >= 768px) { ... } /* 768px以上 */ @media (width <= 767px) { ... } /* 767px以下 */ @media (768px <= width <= 1023px) { ... } /* 範囲指定もスッキリ! */Chrome・Firefox・Safari など主要ブラウザで広くサポートされています。
モバイルファーストで書こう
/* ✅ モバイルファースト(推奨):スマホ向けをデフォルトに */
/* デフォルト:スマホ向け */
.card-list {
display: flex;
flex-direction: column; /* 縦並び */
gap: 16px;
}
/* タブレット以上(768px〜) */
@media (min-width: 768px) {
.card-list {
flex-direction: row; /* 横並びに変更 */
flex-wrap: wrap;
}
}
/* PC以上(1024px〜) */
@media (min-width: 1024px) {
.card-list {
gap: 24px;
}
}
よく使うブレークポイント
| 名前 | 幅 | 対象デバイス |
|---|---|---|
sm |
640px〜 | 大きめのスマホ |
md |
768px〜 | タブレット |
lg |
1024px〜 | 小さめのPC |
xl |
1280px〜 | 普通のPC |
2xl |
1536px〜 | 大きなモニター |
💡 これはTailwind CSSのブレークポイントと同じです!
フレームワークを使う場合もこの値が基準になることが多いです。
レスポンシブ対応のパターン集
/* ① レスポンシブなカードグリッド(Gridを使う) */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
/* ブレークポイントを書かなくてもカード幅が自動調整される! */
}
/* ② フォントサイズをビューポートに応じて変える */
h1 {
font-size: clamp(24px, 5vw, 48px);
/* clamp(最小値, 推奨値, 最大値) */
/* → 最小24px・ビューポート幅の5%・最大48px */
}
/* ③ 画像をレスポンシブにする */
img {
max-width: 100%; /* 親要素の幅を超えない */
height: auto; /* 縦横比を保つ */
}
/* ④ コンテナの幅を制限して中央に配置 */
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto; /* 左右中央揃え */
padding: 0 16px; /* 小さい画面での左右余白 */
}
画面の向き・印刷対応
/* 横向き(landscape)のとき */
@media (orientation: landscape) {
.hero {
min-height: 50vh;
}
}
/* 印刷時のスタイル */
@media print {
.no-print {
display: none; /* 印刷時に非表示 */
}
body {
font-size: 12pt;
color: black;
}
}
7. 🎯 まとめ
| 概念 | 一言で言うと |
|---|---|
| 📦 ボックスモデル | すべての要素はcontent・padding・border・marginの「箱」 |
box-sizing: border-box |
paddingとborderを含めた幅で計算する(現代の標準) |
| 🔧 Flexbox | 1方向(横 or 縦)に要素を並べるレイアウト方法 |
| 🔲 Grid | 行と列の2次元でレイアウトを作る方法 |
| 📍 position | 要素の配置方法(static・relative・absolute・fixed・sticky) |
| 📱 レスポンシブ | メディアクエリで画面サイズに応じてスタイルを変える |
レイアウト選択の早見表
要素を横 or 縦に並べたい → Flexbox
行と列で複雑に配置したい → Grid
要素を画面に固定したい → position: fixed
親要素の右上にバッジを表示 → position: absolute
スクロールで追従させたい → position: sticky
「CSSレイアウトはパズルではなく仕組み」です。
ボックスモデル・Flexbox・Gridの仕組みを理解すれば、
どんなレイアウトも「なぜこう書くのか」を理解しながら実装できます💪
次回は アニメーション・疑似クラス・高度なCSS を解説します!
transition・animation・最新CSS機能を学びましょう🌟
💬 質問や感想があれば、コメント欄でお気軽にどうぞ!
👍 役に立ったら、いいね&ストックをお願いします!
🎓 ここまで読んでくださって、本当にありがとうございました!
🔗 シリーズ記事
- 【第一回】CSSの基礎・セレクター・詳細度・カスケード・CSS変数
- 【第二回】ボックスモデル・Flexbox・Grid・position・レスポンシブ(この記事)
- 【第三回】アニメーション・疑似クラス・高度なCSS(近日公開)
- 【第四回】Tailwind CSS・shadcn/ui・CSSフレームワーク完全解説(近日公開)


