CSS flexbox(フレックスボックス)とは、親要素に display: flex を指定するだけで、子要素を横や縦に並べ、位置・間隔・伸び縮みをまとめて指定できるレイアウトの仕組みです。 横並び、上下左右の中央寄せ、両端揃え、等幅カラムといった定番の配置が、数行のCSSで書けます。

この記事では、justify-contentとalign-itemsの全組み合わせを図にした早見表と、そのまま貼って使えるコピペ用コードをまとめました。間隔の指定はgapを標準にし、flex: 1 の伸縮がどう計算されるかを数値例で確かめ、「指定したのに効かない」ときの原因を再現コードと直し方で整理しています。数値はすべて Chromium 141(Playwright 1.56)で要素の位置とサイズを実測したものです。

flexboxの早見表

やりたいことから書き方を引ける表です。 すべて「親要素」に書くのが基本で、子要素に書くものは明記しています。

やりたいこと 書くCSS 書く場所
横に並べる display: flex; 親
縦に並べる display: flex; flex-direction: column; 親
間隔をあける gap: 16px; 親
左右中央に寄せる justify-content: center; 親
上下中央に寄せる align-items: center;(親に高さが必要) 親
上下左右の中央に置く justify-content: center; align-items: center; 親
両端に揃える justify-content: space-between; 親
右に寄せる justify-content: flex-end; 親
1つだけ右に寄せる margin-left: auto; 子
折り返す flex-wrap: wrap; 親
等幅に並べる flex: 1; 子
幅を固定する flex: 0 0 200px; 子
残りの幅をすべて使う flex: 1; min-width: 0; 子
フッターを下に固定する 親に display: flex; flex-direction: column; min-height: 100vh;、本文に flex: 1; 親と子
1つだけ上下の位置を変える align-self: flex-end; 子
並び順を変える order: -1; 子

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CSS flexboxの使い方早見表|横並び・中央寄せのコピペ集と効かない原因」

flexboxの基本:親と子、主軸と交差軸

flexboxには2つの登場人物がいます。display: flex を指定した親要素(flexコンテナー)と、その直下の子要素(flexアイテム)です。孫要素はflexアイテムにはなりません。

<div class="row">        <!-- 親:flexコンテナー -->
  <div>1</div>           <!-- 子:flexアイテム -->
  <div>2</div>
  <div>3</div>
</div>
.row {
  display: flex;
  gap: 12px;
}

もう1つ押さえておきたいのが軸です。子要素が並ぶ方向を主軸、それと直角の方向を交差軸と呼びます。

flex-directionの値 主軸(並ぶ方向) 交差軸 justify-contentが動かす方向 align-itemsが動かす方向
row(初期値) 左から右 上から下 左右 上下
row-reverse 右から左 上から下 左右 上下
column 上から下 左から右 上下 左右
column-reverse 下から上 左から右 上下 左右

justify-contentは主軸、align-itemsは交差軸を担当します。flex-direction: column にすると2つの役割が入れ替わる点が、最初につまずきやすいところです。

プロパティ一覧(親に書くもの・子に書くもの)

書く場所 プロパティ 役割 初期値
親 display flex(ブロックとして振る舞う)か inline-flex(インラインとして振る舞う) -
親 flex-direction 並ぶ方向 row
親 flex-wrap 折り返すか nowrap
親 justify-content 主軸方向の配置と余白の配り方 normal(flex-startと同じ動き)
親 align-items 交差軸方向の配置 normal(stretchと同じ動き)
親 align-content 折り返した行どうしの配置 normal
親 gap アイテム間の間隔 normal(0と同じ動き)
子 flex 伸びる・縮む・基準サイズをまとめて指定 0 1 auto
子 flex-grow 余った幅を受け取る割合 0
子 flex-shrink 足りない幅を引き受ける割合 1
子 flex-basis 伸縮する前の基準サイズ auto
子 align-self そのアイテムだけ交差軸の配置を変える auto
子 order 並び順(小さいほど前) 0
子 margin: auto 余白をすべて受け取る -

display: flex の親は横幅いっぱいに広がり、display: inline-flex の親は中身の幅に合わせて縮みます。60pxの子2つと gap: 8px で確かめると、flexの親は800px(画面幅)、inline-flexの親は128pxになりました。

justify-content×align-itemsの全組み合わせ図

幅のある箱の中に3つのアイテム(1・2・3)を置いたときの配置図です。横がjustify-content、縦がalign-itemsによる位置を表しています。. は空きスペースです。

justify-content   | align-items:      | align-items:      | align-items:
                  | flex-start        | center            | flex-end
------------------+-------------------+-------------------+------------------
                  | [123............] | [...............] | [...............]
flex-start        | [...............] | [123............] | [...............]
                  | [...............] | [...............] | [123............]
------------------+-------------------+-------------------+------------------
                  | [......123......] | [...............] | [...............]
center            | [...............] | [......123......] | [...............]
                  | [...............] | [...............] | [......123......]
------------------+-------------------+-------------------+------------------
                  | [............123] | [...............] | [...............]
flex-end          | [...............] | [............123] | [...............]
                  | [...............] | [...............] | [............123]
------------------+-------------------+-------------------+------------------
                  | [1......2......3] | [...............] | [...............]
space-between     | [...............] | [1......2......3] | [...............]
                  | [...............] | [...............] | [1......2......3]
------------------+-------------------+-------------------+------------------
                  | [..1....2....3..] | [...............] | [...............]
space-around      | [...............] | [..1....2....3..] | [...............]
                  | [...............] | [...............] | [..1....2....3..]
------------------+-------------------+-------------------+------------------
                  | [...1...2...3...] | [...............] | [...............]
space-evenly      | [...............] | [...1...2...3...] | [...............]
                  | [...............] | [...............] | [...1...2...3...]

align-itemsには、このほかに stretch(初期の動き)と baseline があります。

align-items: stretch(高さを指定していない子が、親の高さいっぱいに伸びる)
[123............]
[123............]
[123............]

align-items: baseline(文字の下端のラインで揃う)
[.2.............]   2 は文字が大きいアイテム
[123............]   1・2・3 の文字の下端が同じ高さに並ぶ
[...............]

justify-contentの実測値

幅300pxの親に、幅60pxの子を3つ入れたときの各アイテムの左端の位置(px)です。余っている幅は 300 − 60×3 = 120px です。

justify-content 1つ目 2つ目 3つ目 余白120pxの配り方
flex-start 0 60 120 すべて右側
center 60 120 180 左右に60pxずつ
flex-end 120 180 240 すべて左側
space-between 0 120 240 アイテムの間に60pxずつ(両端は0)
space-around 20 120 220 各アイテムの左右に20pxずつ(両端20px、間40px)
space-evenly 30 120 210 両端と間をすべて30pxで均等に

space-aroundは両端の余白が間の半分、space-evenlyはすべて同じ幅になります。

align-itemsの実測値

高さ120pxの親に、高さの違う3つのアイテム(A:24px、B:文字を32pxにして48px、C:上に余白20pxを付けて44px)を入れたときの、上端の位置と高さです。

align-items A B C
stretch 上0・高さ120 上0・高さ120 上0・高さ120
flex-start 上0・高さ24 上0・高さ48 上0・高さ44
center 上48・高さ24 上36・高さ48 上38・高さ44
flex-end 上96・高さ24 上72・高さ48 上76・高さ44
baseline 上20・高さ24 上2・高さ48 上0・高さ44

stretch では3つとも親の高さ120pxまで伸びています。baseline では、文字の下端のラインが揃うように、それぞれの上端の位置が変わっています。

9方向の配置コード

1つの要素を箱の中の9か所に置くときの組み合わせです(幅300px・高さ120pxの親に、幅100px・高さ40pxの子を置いて位置を確認済み)。

置きたい位置 justify-content align-items 子の左上の位置
左上 flex-start flex-start (0, 0)
上中央 center flex-start (100, 0)
右上 flex-end flex-start (200, 0)
左中央 flex-start center (0, 40)
中央 center center (100, 40)
右中央 flex-end center (200, 40)
左下 flex-start flex-end (0, 80)
下中央 center flex-end (100, 80)
右下 flex-end flex-end (200, 80)

コピペで使えるflexboxレイアウト集

ここからは、よく使う配置をHTMLとCSSのセットで載せます。クラス名を変えるだけでそのまま使える形にしています。

横並びにして間隔をあける

<ul class="tags">
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>
.tags {
  display: flex;
  gap: 12px;          /* アイテムの間だけに12px */
  list-style: none;
  padding: 0;
  margin: 0;
}

幅60pxの子3つで確かめると、左端の位置は 0・72・144px になりました。間隔はアイテムの間だけに入り、両端には付きません。

上下左右の中央に置く

<div class="center-box">
  <p>中央に表示</p>
</div>
.center-box {
  display: flex;
  justify-content: center; /* 左右の中央 */
  align-items: center;     /* 上下の中央 */
  min-height: 100vh;       /* 画面の高さいっぱいにする(上下中央には高さが必要) */
}

800×600pxの画面に幅200px・高さ100pxの子を置くと、左上の位置は (300, 250) になり、ちょうど中央でした。子が1つだけなら、親を display: flex にして子に margin: auto を指定する書き方でも同じ位置になります。

縦に2つ以上を積んで全体を中央に置きたいときは、flex-direction: column を足します。

.center-stack {
  display: flex;
  flex-direction: column;
  justify-content: center; /* 縦並びでは上下の中央 */
  align-items: center;     /* 縦並びでは左右の中央 */
  gap: 8px;
  min-height: 100vh;
}

両端に揃える(ヘッダー)

ロゴを左、メニューを右に置く定番の形です。

<header class="header">
  <a class="logo" href="/">Logo</a>
  <nav class="nav">
    <a href="/about">会社情報</a>
    <a href="/contact">お問い合わせ</a>
  </nav>
</header>
.header {
  display: flex;
  justify-content: space-between; /* 両端に揃える */
  align-items: center;            /* 上下の中央 */
  height: 56px;
  padding: 0 16px;
}
.nav {
  display: flex;
  gap: 16px;
}

幅600px・高さ56pxで確かめると、幅80pxのロゴは左端(0)、幅140pxのメニューは左から460px、つまり右端にぴったり付きました。

1つだけ右に寄せる

「左にロゴと検索、右端にログインだけ」のように、途中から右に寄せたいときは、寄せたい子に margin-left: auto を指定します。

.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
}
.toolbar .push-right {
  margin-left: auto; /* 余っている幅をすべて左の余白として受け取る */
}

幅300pxの親に幅60pxの子を3つ入れ、3つ目に margin-left: auto を付けると、左端の位置は 0・68・240px になりました。3つ目だけが右端に移動しています。

折り返すカード(幅に合わせて列数が変わる)

<div class="cards">
  <article class="card">カード1</article>
  <article class="card">カード2</article>
  <article class="card">カード3</article>
  <article class="card">カード4</article>
  <article class="card">カード5</article>
</div>
.cards {
  display: flex;
  flex-wrap: wrap;  /* 入りきらない分は次の行へ */
  gap: 16px;
}
.card {
  flex: 1 1 200px;  /* 基準200px。余れば伸び、足りなければ縮む */
}

幅500pxの親で確かめると、1行に2枚(各242px)が並び、5枚目は1枚だけで幅500pxいっぱいに伸びました。

カード 位置 幅
1枚目 (0, 0) 242px
2枚目 (258, 0) 242px
3枚目 (0, 66) 242px
4枚目 (258, 66) 242px
5枚目 (0, 132) 500px

折り返すカード(3列に固定して最後の行も同じ幅にする)

最後の行のカードも同じ幅に保ちたいときは、伸びない設定(flex-grow: 0)にして、幅を計算で決めます。

.cards-3col {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}
.cards-3col .card {
  /* (全体の幅 − 間隔2つ分)÷ 3 */
  flex: 0 1 calc((100% - 16px * 2) / 3);
}

幅500pxの親では、カードは各156pxになり、4枚目と5枚目は2行目の左から順に並びました(位置は (0, 66) と (172, 66))。列数をきっちり決めたい一覧では、CSS Gridの grid-template-columns: repeat(3, 1fr) も同じ見た目を短く書けます。

フッターを画面の下に固定する

本文が短いページでも、フッターを画面の一番下に置く書き方です。

<body class="page">
  <header>ヘッダー</header>
  <main>本文</main>
  <footer>フッター</footer>
</body>
.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh; /* 画面の高さ以上にする */
  margin: 0;
}
.page > main {
  flex: 1;           /* 余った高さをすべて本文が受け取る */
}

min-height: 400px の親に、高さ50pxのヘッダーと高さ40pxのフッターを入れて確かめると、本文は高さ310pxまで伸び、フッターは上から360pxの位置、つまり下端にぴったり付きました。

等幅のカラムに分ける

.columns {
  display: flex;
  gap: 20px;
}
.columns > * {
  flex: 1;      /* 余った幅を同じ割合で分け合う */
  min-width: 0; /* 中身が長くても等幅を保つ */
}

幅600pxで gap: 20px、子3つのとき、各カラムは186.7pxになりました((600 − 20×2) ÷ 3)。

サイドバー固定+メイン可変

.layout {
  display: flex;
  gap: 24px;
}
.sidebar {
  flex: 0 0 200px; /* 伸びない・縮まない・幅200px */
}
.main {
  flex: 1;         /* 残りすべて */
  min-width: 0;
}

幅800pxの親では、サイドバーが200px、メインが576px(800 − 200 − 24)になりました。

アイコン+1行で省略するテキスト

<div class="item">
  <img class="icon" src="icon.png" alt="" width="40" height="40">
  <div class="body">
    <p class="title">長いタイトルが入っても1行で省略して表示します</p>
  </div>
</div>
.item {
  display: flex;
  align-items: center;
  gap: 8px;
}
.icon {
  flex-shrink: 0;  /* アイコンは縮めない */
}
.body {
  flex: 1;
  min-width: 0;    /* これがないと中の文字が省略されずにはみ出す */
}
.title {
  margin: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

min-width: 0 が必要な理由は、後半の「効かない原因」で実測値とあわせて説明します。

間隔はgapで指定する

アイテムどうしの間隔は、親に gap を書くのが最も手軽です。 marginで間隔をあける方法と比べると、両端の余白を打ち消す指定がいらなくなります。

書き方 意味
gap: 16px; 縦横とも16px
gap: 8px 20px; 行の間8px、列の間20px(row-gap、column-gapの順)
row-gap: 8px; 行の間だけ
column-gap: 20px; 列の間だけ

幅300pxの親で、幅140pxの子4つを flex-wrap: wrap; gap: 8px 20px; で並べると、位置は (0, 0)・(160, 0)・(0, 38)・(160, 38) になりました。列の間が20px、行の間が8pxです。

flexboxでのgapは、MDNのブラウザー対応データ(npmパッケージ @mdn/browser-compat-data 8.1.4)によると Chrome 84、Edge 84、Firefox 63、Safari 14.1(iOS Safari 14.5)以降で使えます。現在の主要ブラウザーではそのまま使える機能です。

gapとmarginの違い

比べる点 gap margin
書く場所 親に1回 子すべて
両端の余白 付かない 付く(最後の子だけ0にする指定が必要)
折り返したときの行間 自動で入る 上下のmarginも別に必要
space-betweenとの併用 gapが「最小の間隔」になる 余白に足される

space-betweenと併用した例として、幅300px・子60px×3で justify-content: space-between; gap: 12px; と書くと、位置は 0・120・240px でした。余白が十分あるので間隔は60pxのままです。画面が狭くなって余白がなくなっても、12pxの間隔は確保されます。

なお、通常のブロック要素では上下に隣り合うmarginが重なって1つになります(marginの相殺)が、flexアイテムどうしのmarginは相殺されません。 下20pxと上20pxのmarginを持つ2つの子で確かめると、通常のブロックでは2つ目が上から50px、縦並びのflexでは70pxの位置になりました。

flex:1の伸縮計算を数値で理解する

flex は、flex-grow(伸びる割合)・flex-shrink(縮む割合)・flex-basis(基準サイズ)の3つをまとめて書くプロパティです。書き方ごとに実際に設定される値を、getComputedStyle で確認しました。

書き方 flex-grow flex-shrink flex-basis 動き
(指定なし) 0 1 auto 伸びない・縮む・中身の幅が基準
flex: 1 1 1 0% 伸びる・縮む・基準0
flex: auto 1 1 auto 伸びる・縮む・中身の幅が基準
flex: none 0 0 auto 伸びない・縮まない
flex: 2 100px 2 1 100px 100pxを基準に2の割合で伸びる
flex: 0 0 200px 0 0 200px 200px固定

計算の流れ

flexboxは、次の順番でアイテムの幅を決めます。

flowchart TD
  A["各アイテムの基準サイズ flex-basis を合計する"] --> B{"親の幅(gapを引いた分)と比べる"}
  B -- "余っている" --> C["余りを flex-grow の比で配る"]
  B -- "足りない" --> D["不足分を flex-shrink × flex-basis の比で引く"]
  B -- "ちょうど" --> E["基準サイズのまま"]

伸びる計算:flex-growの比で余りを配る

幅600pxの親に3つの子を入れ、flex: 1・flex: 2・flex: 1 と指定した例です。

  • 基準サイズは3つとも0なので、余りは 600 − 0 = 600px
  • flex-growの合計は 1 + 2 + 1 = 4
  • 1つ分は 600 ÷ 4 = 150px
アイテム 指定 計算 実測の幅
1つ目 flex: 1 0 + 150 × 1 150px
2つ目 flex: 2 0 + 150 × 2 300px
3つ目 flex: 1 0 + 150 × 1 150px

flex:1とflex:autoの違い

同じ「伸びる」指定でも、基準サイズが0かautoかで結果が変わります。 中身の幅が100px・200px・100pxの子3つを、幅600pxの親に入れて比べました。

指定 基準サイズの合計 余り 1つ目 2つ目 3つ目
flex: 1 0 600 200px 200px 200px
flex: auto 400(100+200+100) 200 166.7px 266.7px 166.7px
flex: none 400 (配らない) 100px 200px 100px
指定なし 400 (配らない) 100px 200px 100px
  • flex: 1 は中身に関係なく等分します(幅そのものを比で分ける)。
  • flex: auto は中身の幅を確保したうえで、余りだけを等分します(200 ÷ 3 ≒ 66.7pxずつ足される)。

等幅のカラムを作りたいときは flex: 1、中身の長さに応じた幅にしつつ余白を埋めたいときは flex: auto を選びます。

gapがあるときの計算

gapは先に親の幅から引かれます。幅600px、gap: 20px、子3つに flex: 1 のとき、配る幅は 600 − 20×2 = 560px、1つ分は 560 ÷ 3 ≒ 186.7px で、実測も186.7pxでした。

flex-growの合計が1未満のとき

flex-growの合計が1より小さい場合は、余りの全部ではなく、その割合ぶんだけが配られます。幅600pxの親に flex: 0.2 と flex: 0.3 の子を入れると、幅は120px(600×0.2)と180px(600×0.3)になり、残りの300pxは空いたままでした。

縮む計算:flex-shrink×flex-basisの比で引く

親の幅より基準サイズの合計が大きいときは、不足分を各アイテムから引きます。縮む量は「flex-shrink × flex-basis」の比で決まるので、同じflex-shrinkでも、基準サイズが大きいアイテムほど多く縮みます。

幅400pxの親に、基準サイズ300px・200px・100pxの子を入れた例です(合計600px、不足200px)。

アイテム flex-shrink × flex-basis 比 縮む量 実測の幅
1つ目(300px) 1 × 300 = 300 300/600 200 × 300/600 = 100 200px
2つ目(200px) 1 × 200 = 200 200/600 200 × 200/600 ≒ 66.7 133.3px
3つ目(100px) 1 × 100 = 100 100/600 200 × 100/600 ≒ 33.3 66.7px

1つ目だけ flex-shrink: 2 にすると、比の分母が 2×300 + 200 + 100 = 900 に変わります。

アイテム flex-shrink × flex-basis 縮む量 実測の幅
1つ目(shrink 2) 600 200 × 600/900 ≒ 133.3 166.7px
2つ目 200 200 × 200/900 ≒ 44.4 155.6px
3つ目 100 200 × 100/900 ≒ 22.2 77.8px

中身の幅より小さくは縮まない(min-width: auto)

flexアイテムには、初期状態で「中身の最小幅より小さくならない」という決まりがあります(min-width: auto)。この決まりが flex: 1 の等分にも影響します。

幅600pxの親に flex: 1 の子を3つ入れ、2つ目の中に幅300pxの要素を入れた例です。

指定 1つ目 2つ目(中に300pxの要素) 3つ目
flex: 1 150px 300px 150px
flex: 1; min-width: 0; 200px 200px 200px

flex: 1 だけでは、2つ目が中身の300pxを確保し、残りの300pxを他の2つで分けています。min-width: 0 を足すと、中身に関係なく200pxずつの等分になります(中身ははみ出すので、overflow: hidden などと組み合わせます)。

flexboxが効かない原因と直し方

「指定したのに動かない」ときに確認したい原因を、再現コードと実測値つきでまとめました。

症状 主な原因 直し方
横に並ばない・中央に寄らない 親に display: flex がない 親に display: flex を書く
上下中央にならない 親の高さが子と同じ 親に height か min-height を指定
align-content が効かない 折り返していない align-items を使う、または flex-wrap: wrap を付ける
テキストが省略されずにはみ出す min-width: auto 子に min-width: 0
width を指定したのに狭くなる flex-shrink: 1 で縮んでいる flex: 0 0 幅 または flex-shrink: 0
縦並びにしたら中央寄せの向きが変わった 主軸と交差軸が入れ替わった justify-contentとalign-itemsを入れ替える
justify-self が効かない flexboxでは無視される margin-left: auto などを使う
折り返した最後の行が両端に分かれる space-between が行ごとに働く gap と幅の計算に切り替える
中央寄せの中身が大きいと左が切れる 両側に均等にはみ出す justify-content: safe center
縦並びの中でスクロールしない min-height: auto 子に min-height: 0

原因1:親に display: flex を指定していない

justify-contentやalign-itemsは親に書くプロパティで、その親が display: flex になっていることが前提です。

/* 直す前:display: flex がない */
.box {
  width: 300px;
  height: 120px;
  justify-content: center;
  align-items: center;
}

/* 直した後 */
.box {
  display: flex;
  width: 300px;
  height: 120px;
  justify-content: center;
  align-items: center;
}
状態 子(幅100px・高さ40px)の位置
直す前 (0, 0)(左上のまま)
直した後 (100, 40)(中央)

動かしたい要素自身に justify-content を書いている場合も同じです。書く場所は「動かしたい要素の1つ上の親」と覚えておくと確認しやすくなります。開発者ツールでは、flexの親要素の横に「flex」というバッジが表示されるので、そこで見分けられます。

原因2:親に高さがない

align-items: center は、親の高さの中で子を上下中央に置きます。親に高さの指定がないと、親の高さは子と同じになり、動く余地がありません。

/* 直す前:親の高さは子と同じ40pxになる */
.box { display: flex; align-items: center; }

/* 直した後:高さを指定する */
.box { display: flex; align-items: center; height: 120px; }
状態 親の高さ 子(高さ40px)の上端
直す前 40px 0
直した後 120px 40(上下中央)

画面全体の中央に置きたいときは min-height: 100vh を使います。height: 100% は、さらにその親にも高さが指定されている場合に働きます。

原因3:align-itemsとalign-contentの混同

名前が似ていますが、役割が違います。

プロパティ 何を揃えるか 折り返しなし(nowrap)のとき
align-items 各行の中でのアイテムの位置 効く
align-content 折り返した行のかたまり全体の位置 効かない

幅300px・高さ120pxの親に子(高さ40px)を1つ入れて確かめました。

指定 子の上端
align-content: center(折り返しなし) 0(効いていない)
align-content: center + flex-wrap: wrap 40(中央)
align-items: center(折り返しなし) 40(中央)

折り返して2行になったときの違いも見てみます。幅300px・高さ200pxの親に、幅140px・高さ40pxの子を4つ入れた結果です。

指定 1行目の上端 2行目の上端 見え方
align-items: center 30 130 親を上下2つに分け、それぞれの中央に置く
align-content: center 60 100 2行をくっつけたまま、全体を中央に置く

1行のときはalign-items、複数行のかたまりを動かしたいときはalign-contentと使い分けます。

なお、flexではない通常のブロック要素でも、align-content: center で中身を上下中央に置けるようになっています(MDNのデータでは Chrome 123、Firefox 125、Safari 17.4 以降)。Chromium 141 で、display: flex なしの高さ120pxの箱に指定したところ、子の上端は40になりました。

原因4:min-width: auto ではみ出す

flex: 1 を指定したのにテキストが省略されず、親からはみ出す場合は、先ほどの min-width: auto が関係しています。

/* 共通:flexアイテム(.body)の中にある p に省略の指定を書いている */
.title { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* 直す前 */
.body { flex: 1; }

/* 直した後 */
.body { flex: 1; min-width: 0; }

幅300pxの親に、幅40pxのアイコンと、長いURLを入れたテキスト領域(.body)を並べて確かめました。

状態 テキスト領域の幅 親の中身の幅(scrollWidth)
flex: 1 のみ 915.1px 963px(はみ出す)
flex: 1; min-width: 0; 252px 300px(親の中に収まる)

省略の指定(overflow: hidden)をflexアイテム自身に書いた場合は、min-widthの自動的な最小幅が0として扱われるため、min-width: 0 がなくても252pxに収まりました。はみ出すのは、flexアイテムの「中の要素」が長いときです。「flex: 1 と min-width: 0 はセット」と覚えておくと、長いテキストやコードブロック、表を含むレイアウトで役立ちます。縦並び(flex-direction: column)では同じことが高さで起こるので、min-height: 0 を使います。高さ200pxの縦並びの親で、高さ500pxの中身を持つ子に flex: 1 を指定すると、子の高さは500pxになって親からはみ出し、min-height: 0; overflow: auto; を足すと160pxに収まってスクロールできるようになりました。

原因5:widthを指定したのに狭くなる

flexアイテムは初期状態で flex-shrink: 1 なので、入りきらないときはwidthを指定していても縮みます。

指定 親300pxの中での幅
子2つに width: 200px 150px・150px(縮んでいる)
1つ目 flex: 0 0 200px、2つ目 flex: 1 200px・100px
幅100pxの子5つ(折り返しなし) 60pxずつ
幅100pxの子5つに flex-shrink: 0 100pxずつ(親からはみ出して中身の幅は500px)

幅を保ちたいアイテムには flex: 0 0 200px または flex-shrink: 0 を指定します。はみ出させたくない場合は、親に flex-wrap: wrap を付けて折り返します。

原因6:縦並びにしたら向きが変わった

flex-direction: column では、justify-contentが上下、align-itemsが左右を担当します。幅300px・高さ200pxの縦並びの親で確かめました。

指定 子(幅100px・高さ40px)の位置 動いた方向
justify-content: center (0, 80) 上下
align-items: center (100, 0) 左右

原因7:justify-selfやjustify-itemsが効かない

justify-self と justify-items はCSS Grid向けのプロパティで、flexboxでは無視されます(指定しても子の位置は (0, 0) のままでした)。flexboxで1つだけ主軸方向に動かしたいときは、margin-left: auto や margin-right: auto を使います。交差軸方向なら align-self が使えます。

原因8:折り返した最後の行が両端に分かれる

justify-content: space-between は行ごとに働くため、最後の行のアイテム数が少ないと、間が大きくあきます。幅500pxの親に幅150pxの子を5つ入れると、2行目は (0, 50) と (350, 50) に分かれました。左から順に詰めたいときは、コピペ集の「3列に固定」の書き方(gap と calc で幅を決める)にすると、2行目が (0, 66)・(172, 66) と左詰めになります。

原因9:中央寄せの中身が大きいと左側が見えなくなる

justify-content: center は、中身が親より大きいとき、左右に均等にはみ出します。 左側にはみ出した部分はスクロールでも表示できません。

指定(親200px・子300px・overflow: auto) 子の左端 スクロールできる幅
justify-content: center −50px(左に50pxはみ出す) 50px
justify-content: safe center 0 100px(全体を表示できる)

safe を付けると、はみ出すときだけ先頭揃えに切り替わります。MDNのデータでは Chrome 115、Firefox 63、Safari 17.6 以降で使えます。

よくある質問

Q. justify-contentとalign-itemsはどう覚えればよいですか? A. justify-contentは「並んでいる方向(主軸)」、align-itemsは「それと直角の方向(交差軸)」です。横並び(初期状態)なら、justify-contentが左右、align-itemsが上下になります。縦並びにすると入れ替わります。

Q. flex: 1 は何の略ですか? A. flex: 1 1 0%、つまり flex-grow: 1、flex-shrink: 1、flex-basis: 0% の略です。基準サイズを0にして、親の幅を同じ割合で分け合う指定になります。

Q. gapとmarginはどちらを使えばよいですか? A. アイテムどうしの間隔はgapが手軽です。親に1回書くだけで、両端に余白が付かず、折り返したときの行間も入ります。「1つだけ右に寄せる」のように特定のアイテムを動かしたいときは、margin-left: auto を使います。

Q. flexboxとCSS Gridはどう使い分けますか? A. 1方向に並べて、中身の量に合わせて伸び縮みさせたいときはflexbox、行と列の両方をそろえた格子状の配置にしたいときはGridが向いています。ヘッダーやボタンの並び、タグの一覧はflexbox、カードを決まった列数で並べる一覧やページ全体の枠組みはGrid、という分け方がよく使われます。

まとめ

  • 親に display: flex を書くと、直下の子が横に並ぶ。間隔は親の gap で指定する。
  • justify-contentは主軸(横並びなら左右)、align-itemsは交差軸(横並びなら上下)。縦並びにすると入れ替わる。
  • 上下左右の中央は justify-content: center; align-items: center;。上下中央には親の高さが必要。
  • flex: 1 は 1 1 0% の略で、親の幅を比で分ける。flex: auto は中身の幅を確保してから余りを配る。
  • 縮む量は「flex-shrink × flex-basis」の比で決まり、幅を保ちたいアイテムには flex: 0 0 幅 を使う。
  • 長いテキストがはみ出すときは min-width: 0(縦並びなら min-height: 0)を足す。
  • 効かないときは「親に書いているか」「親に高さがあるか」「折り返しの有無」の3点から確認する。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「CSS flexboxの使い方早見表|横並び・中央寄せのコピペ集と効かない原因」

株式会社RJCでは、CSSのレイアウトの仕組みと書き方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?