HTML/CSS:Flexbox
1学習の目的
- Flexboxで要素を横並びにし、間隔や位置を自在に制御できるようになる。inline-block の弱点(隙間・中央揃えの難しさ)がすべて解決する。
- 縦方向の中央揃えができるようになる。CSSで長年「難しい」とされてきた問題が、1行で解決することを体験する。
2基礎解説
親要素に display: flex を指定するだけで、中の要素が横並びになります。あとは親側のプロパティで配置を調整していきます。
| プロパティ | 役割 | よく使う値 |
|---|---|---|
| display: flex | 横並びにする | これが出発点 |
| justify-content | 横方向の配置 | center / space-between |
| align-items | 縦方向の配置 | center |
| gap | 要素同士の間隔 | 16px / 24px |
- 指定するのは「親」、動くのは「子」。display: flex は親に書き、子は自動的に横並びになる。子側に何も書かなくてよい。
- justify-content は横、align-items は縦。この2つを組み合わせれば、上下左右の中央揃えが2行で完成する。
- gap で間隔を空ける。margin と違い、両端に余分な余白が付かないので、等間隔の配置が簡単になる。
- flex: 1 で残りの幅を埋める。固定幅の要素と組み合わせれば、「片方は固定、もう片方は伸縮」というレイアウトが作れる。
- 既定では折り返さない。画面が狭いと要素が縮んでしまうので、flex-wrap: wrap を指定すると折り返すようになる(レスポンシブで重要)。
現場使用例:ナビゲーションバー、カードの横並び、ヘッダーのロゴとメニュー、ボタンの並び、フォームの入力欄とボタン。現代のWebレイアウトの中心的な技術。
/* 基本:親に display: flex */
.container {
display: flex;
}
/* 横方向の配置 */
.container {
display: flex;
justify-content: center; /* 中央 */
/* flex-start(左)/ flex-end(右)
space-between(両端に寄せて等間隔)
space-around(周囲に均等な余白) */
}
/* 縦方向の配置 */
.container {
display: flex;
align-items: center; /* 縦中央 */
height: 200px;
}
/* ⭐ 上下左右の完全な中央揃え */
.center {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
}
/* 等間隔に配置(両端に余白なし) */
.list {
display: flex;
gap: 20px;
}
/* 片方を固定、もう片方を伸縮 */
.layout { display: flex; }
.sidebar { width: 200px; } /* 固定 */
.main { flex: 1; } /* 残り全部 */
/* 縦並びに変える */
.vertical {
display: flex;
flex-direction: column;
}
/* 画面が狭いとき折り返す */
.cards {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
3基本ドリル(10問)
3つが横に並ぶ
親に display: flex; を指定するだけ。子には何も書かなくてよい。
<style>
.container {
display: flex;
}
.box {
width: 100px;
height: 50px;
background-color: #ccc;
}
</style>
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>div は block なのに横に並んだ。親が flex になると、子の display は無視されて自動的に横並びになる。
A. 並べたい要素すべて B. 親要素だけ C. body D. 子要素だけ 選択★☆☆無料
解答 == B
指定するのは1箇所だけ。
B
親に1行書くだけ。子側には何も指定しなくてよいので、inline-block より記述量が少ない。
justify-content が center
justify-content: center; を使う。
<style>
.container {
display: flex;
justify-content: center;
width: 600px;
}
.box {
width: 100px;
height: 50px;
background-color: #ccc;
}
</style>
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
</div>justify-content は横方向の配置を決める。center のほか、flex-end(右寄せ)や space-between(両端寄せ)がある。
<style>
.container {
display: flex;
____: center;
height: 200px;
}
</style>
<div class="container">
<div>縦中央</div>
</div>align-items が center
「項目を揃える」を意味する11文字のプロパティ(ハイフン含む)。
align-items
align-items は縦方向。justify-content(横)と対になっており、この2つで上下左右の配置が決まる。
A. center B. space-between C. flex-end D. stretch 選択★☆☆無料
解答 == B
「間にスペースを配る」という意味の値。
B
space-between は最初と最後を端に置き、間を均等に空ける。ヘッダーで「ロゴを左、メニューを右」にするときの定番。
justify-contentとalign-itemsが両方center
justify-content と align-items の両方を center にする。
<style>
.center {
display: flex;
justify-content: center;
align-items: center;
width: 400px;
height: 300px;
background-color: #eee;
}
</style>
<div class="center">
<p>完全な中央</p>
</div>たった2行で上下左右の中央揃えが完成する。Flexbox以前は、この単純な要求に複雑な手法が必要だった。
<style>
.container {
display: flex;
____: 20px;
}
.box { width: 100px; }
</style>
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
</div>gap が 20px
「隙間」を意味する3文字のプロパティ。
gap
gap は要素の「間」だけに余白を作る。margin と違って両端に余分な余白が付かないので、等間隔の配置が簡単になる。
A. 幅が1pxになる B. 残りの幅をすべて埋める C. 1番目に表示される D. 変化しない 選択★★☆広告解放
解答 == B
余った空間をどう使うかの指定。
B
他の要素の幅を引いた残り全部に広がる。「サイドバーは200px固定、本文は残り全部」というレイアウトが簡単に作れる。
サイドバー200px、本文300px
サイドバーに width: 200px、本文に flex: 1 を指定する。
<style>
.layout {
display: flex;
width: 500px;
}
.sidebar {
width: 200px;
background-color: #ddd;
}
.main {
flex: 1;
background-color: #f5f5f5;
}
</style>
<div class="layout">
<div class="sidebar">サイドバー</div>
<div class="main">本文</div>
</div>本文は自動的に300pxになる(500 − 200)。親の幅が変わっても、本文が伸縮して隙間なく収まる。
flex-direction が column
flex-direction: column; を指定する。
<style>
.container {
display: flex;
flex-direction: column;
}
.box {
height: 40px;
background-color: #ccc;
}
</style>
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
</div>column にすると縦に積まれる。このとき justify-content が縦方向、align-items が横方向に入れ替わる点に注意。
4実践シナリオ(5問)
space-betweenとalign-items:centerが正しい
justify-content: space-between; と align-items: center; を組み合わせる。
<style>
header {
display: flex;
justify-content: space-between;
align-items: center;
width: 800px;
height: 60px;
padding: 0 20px;
box-sizing: border-box;
background-color: #f5f5f5;
}
nav a {
margin-left: 16px;
text-decoration: none;
}
</style>
<header>
<div class="logo">ゼロカラカフェ</div>
<nav>
<a href="#">ホーム</a>
<a href="#">メニュー</a>
</nav>
</header>これが現代的なヘッダーの標準形。space-between で両端に寄せ、align-items で高さの中央に揃える——2行でほぼ完成する。
gapが20px、3つが等間隔
gap を使えば margin より簡単に等間隔になる。
<style>
.cards {
display: flex;
gap: 20px;
}
.card {
width: 150px;
height: 100px;
background-color: #ddd;
}
</style>
<div class="cards">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
</div>margin-right だと最後の要素にも余白が付いてしまう。gap なら間だけに空くので、余計な調整が不要になる。
上下左右とも中央
justify-content と align-items の両方を center にする。
<style>
.hero {
display: flex;
justify-content: center;
align-items: center;
width: 500px;
height: 200px;
background-color: #eee;
}
.btn {
padding: 12px 32px;
background-color: #0066cc;
color: #ffffff;
border: none;
border-radius: 4px;
}
</style>
<div class="hero">
<button class="btn">今すぐ始める</button>
</div>ヒーローエリアの定番。中身が何であっても(文字・ボタン・画像)、この2行で確実に中央に来る。
3つ目が2行目に折り返す
flex-wrap: wrap; を指定しないと、カードが縮んで1行に収まってしまう。
<style>
.cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
width: 250px;
}
.card {
width: 100px;
height: 60px;
background-color: #ddd;
}
</style>
<div class="cards">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
</div>wrap が無いと、カードが潰れて1行に押し込まれる。指定した幅が守られなくなるので、カード一覧では必須の指定になる。
入力欄が伸縮、ボタンが120px
入力欄に flex: 1、ボタンに width: 120px を指定する。
<style>
.search {
display: flex;
gap: 8px;
width: 500px;
}
.search input {
flex: 1;
padding: 10px;
border: 1px solid #ccc;
}
.search button {
width: 120px;
background-color: #0066cc;
color: #ffffff;
border: none;
}
</style>
<div class="search">
<input type="text" placeholder="検索キーワード">
<button>検索</button>
</div>入力欄が残りの幅をすべて使う。画面幅が変わってもボタンは120pxのまま、入力欄だけが伸縮する——検索フォームの定番構成。
5仕上げ課題
① ヘッダー(.header)
・display: flex、space-between、縦中央
・幅 900px、高さ 64px、padding 0 24px、box-sizing 指定
・中身:div.logo と nav(nav の中に a × 2、gap は nav 側で 20px)
② カード一覧(.cards)
・display: flex、flex-wrap: wrap、gap: 24px、幅 900px
・.card:幅 280px、padding 20px、枠線 1px solid #ddd、box-sizing 指定
・カードを3つ配置(各カードに h3 と p)
③ 2カラム(.layout)
・display: flex、gap: 24px、幅 900px
・.sidebar:幅 240px 固定
・.main:flex: 1(残り全部)
確認したいこと
・カードは3つとも1行に収まる(280×3 + 24×2 = 888 ≤ 900)
・.main の幅が636px(900 − 240 − 24) 総合★★★広告解放
すべてのレイアウトと寸法が正しい
nav にも display: flex と gap を指定する。カードは 280px × 3 + gap 24px × 2 = 888px なので900pxに収まる。main は flex: 1 で残り幅(900 - 240 - 24 = 636px)になる。
<style>
* {
box-sizing: border-box;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
width: 900px;
height: 64px;
padding: 0 24px;
background-color: #f5f5f5;
}
.header nav {
display: flex;
gap: 20px;
}
.header a {
text-decoration: none;
color: #0066cc;
}
.cards {
display: flex;
flex-wrap: wrap;
gap: 24px;
width: 900px;
}
.card {
width: 280px;
padding: 20px;
border: 1px solid #ddd;
}
.layout {
display: flex;
gap: 24px;
width: 900px;
}
.sidebar {
width: 240px;
background-color: #eee;
}
.main {
flex: 1;
background-color: #f9f9f9;
}
</style>
<div class="header">
<div class="logo">ゼロカラカフェ</div>
<nav>
<a href="#">ホーム</a>
<a href="#">メニュー</a>
</nav>
</div>
<div class="cards">
<div class="card">
<h3>ブレンドコーヒー</h3>
<p>当店自慢の一杯です。</p>
</div>
<div class="card">
<h3>季節のケーキ</h3>
<p>旬の素材を使っています。</p>
</div>
<div class="card">
<h3>ランチセット</h3>
<p>平日限定でご用意。</p>
</div>
</div>
<div class="layout">
<div class="sidebar">サイドバー</div>
<div class="main">本文エリア</div>
</div>3種類のレイアウトが、すべて Flexbox だけで組めている。ヘッダーの両端配置、カードの折り返し、2カラム——かつては float や position を駆使して実現していたものが、数行で書ける。
.main { flex: 1; } の計算に注目してほしい。親が900px、サイドバーが240px、gap が24px——残りの636pxを main が自動的に埋める。数値を計算して書く必要がないのが重要で、親の幅が変わっても常に隙間なく収まる。
カードの flex-wrap: wrap も欠かせない。280px × 3 + gap 48px = 888px でギリギリ収まっているが、もし親が800pxになれば3つ目が自動的に次の行へ折り返す。wrap が無ければカードが潰れて幅280pxが守られない。
そして gap だ。margin で間隔を作ると最後の要素にも余白が付いて右端がずれるが、gap なら間だけに空く。この小さな違いが、レイアウトの精度を大きく左右する。
次章では Grid を学ぶ。Flexbox が1方向の並びを得意とするのに対し、Grid は行と列の両方を同時に制御できる——用途に応じた使い分けを身につける。