CSSの中央寄せは、「何を(テキストか箱か)」と「どの方向に(横・縦・両方)」の2つを決めれば、使うプロパティが1つに決まります。 迷ったら、親に display: grid; place-items: center; を書くのがいちばん短く、上下左右の中央がそろいます。

この記事では、よく使う中央寄せの方法を「何を×どの方向」で引ける早見表にまとめ、すべてのパターンを Chromium 141(Playwright 1.56)で描画し、子要素の左右・上下の余白を getBoundingClientRect() で実測した数値 といっしょに紹介します。左右の余白が同じなら横中央、上下の余白が同じなら縦中央、と数字で確かめられます。さらに「中央にならない」ときによくある原因を実際に再現し、直す前と後を並べました。


CSS 中央寄せの早見表

まずはこの表で、自分のケースに合う1行を探してください。 書く場所(親/子)に注意すると、ほとんどの「効かない」は防げます。

何を 横だけ 縦だけ 上下左右
テキスト・インライン要素(span、a、文字) 親に text-align: center 親に align-content: center(高さが必要)/1行なら line-height: 高さ 親に display: grid; place-items: center
幅のあるブロック要素(div) 子に margin-inline: auto(幅の指定が必要) 親に align-content: center 親に display: grid; place-items: center
幅が中身に合う箱(ボタン風) 子に width: fit-content; margin-inline: auto 親に align-content: center 親に display: grid; place-items: center
画像 img 子に display: block; margin-inline: auto(または親に text-align: center) 親をflex/gridにする 親に display: grid; place-items: center
フレックスアイテム 親に justify-content: center 親に align-items: center 親に両方、または子に margin: auto
グリッドアイテム 親に justify-items: center 親に align-items: center 親に place-items: center
複数の子をひとかたまりで 親をflexにして justify-content: center 親を flex-direction: column にして justify-content: center 親に display: grid; place-content: center
重ねて置く要素(position: absolute) left: 0; right: 0; margin-inline: auto top: 0; bottom: 0; margin-block: auto inset: 0; margin: auto(幅・高さが必要)/ top: 50%; left: 50%; transform: translate(-50%, -50%)
画面中央のモーダル ― ― <dialog> を showModal()(既定で中央)/ position: fixed; inset: 0; display: grid; place-items: center の背景
表のセル text-align: center vertical-align: middle 両方

判断の早見(どれを選ぶか)

状況 おすすめ 理由
とにかく上下左右の中央にしたい display: grid; place-items: center 親の2行だけで済み、子のサイズを知らなくてよい
子を横に並べつつ中央にしたい Flexbox(justify-content / align-items) 並べ方(方向・間隔)も同時に決められる
親を flex/grid にしたくない(レイアウトを変えたくない) ブロックの align-content: center + margin-inline: auto 通常のブロックのまま縦中央にできる
他の要素の上に重ねたい position: absolute + inset: 0; margin: auto 周りの配置に影響しない
子のサイズが分からない重ね配置 top/left: 50% + transform: translate(-50%, -50%) 幅・高さの指定がいらない
子が親より大きくなることがある justify-content: safe center または子に margin: auto はみ出したときに左端が切れない

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

(記載例)出典:株式会社RJC「CSS 中央寄せの方法|横・縦・上下左右の早見表と実測結果15パターン」


実測結果:15パターンの余白を数値で確認

検証条件:親 300×200px(box-sizing: border-box、余白0)、子 100×60px(テキストは文字の範囲を Range.getBoundingClientRect() で測定)。ビューポート 800×600、Chromium 141.0.7390.37(Playwright 1.56.0)。L/R/T/B は親の左・右・上・下の辺から子までの距離(px)です。

# 方法 L R T B 横 縦
1 親 text-align: center(テキスト) 94 94 3 180 中央 上
2 子 margin-inline: auto 100 100 0 140 中央 上
3 親 flex + justify-content/align-items: center 100 100 70 70 中央 中央
4 親 flex + 子 margin: auto 100 100 70 70 中央 中央
5 親 grid + place-items: center 100 100 70 70 中央 中央
6 親 grid + place-content: center 100 100 70 70 中央 中央
7 親(ブロック)align-content: center + 子 margin-inline: auto 100 100 70 70 中央 中央
8 position: absolute; inset: 0; margin: auto 100 100 70 70 中央 中央
9 top/left: 50% + translate(-50%, -50%) 100 100 70 70 中央 中央
10 line-height: 200px + text-align: center(1行テキスト) 105.5 105.5 91 92 中央 中央
11 display: table-cell; vertical-align: middle 94 94 91 92 中央 中央
12 width: fit-content; margin-inline: auto 94 94 0 176 中央 上
13 img { display: block; margin-inline: auto } 100 100 0 140 中央 上
14 親 text-align: center + 子 inline-block 100 100 0 176 中央 上
15 flex 縦並び(column)+ justify-content/align-items 100 100 70 70 中央 中央
参考 <dialog>.showModal()(200×100、ビューポート基準) 300 300 250 250 中央 中央

上下左右の中央(L=R かつ T=B)になったのは、3〜11・15と <dialog> でした。 #10・#11の上下が1px違うのは、テキストの字面の高さ(17px)が行の高さの中で上下均等にならない(フォントの上下の余白が違う)ためで、行ボックスとしては中央です。


横の中央寄せ

テキスト・インライン要素を横中央にする(text-align)

text-align: center は親に書き、親の中の「文字や inline 要素」を中央に寄せます。 子の div そのものは動きません。

<div class="parent">
  <span>中央のテキスト</span>
</div>
.parent {
  text-align: center;
}

実測(#1):L=94 / R=94。文字の範囲が左右均等になりました。

ブロック要素を横中央にする(margin-inline: auto)

幅を指定したブロック要素は、左右の margin を auto にすると横中央になります。 margin-inline: auto は margin-left: auto; margin-right: auto; と同じ意味の新しい書き方(論理プロパティ)で、縦書きでも「行の方向」に効きます。従来の margin: 0 auto でも同じ結果です。

<div class="parent">
  <div class="child"></div>
</div>
.child {
  width: 100px;          /* 幅がないと親いっぱいに広がり、中央かどうか分からない */
  margin-inline: auto;
}

実測(#2):L=100 / R=100。

幅を中身に合わせて横中央にする(fit-content)

ボタン風の要素のように「幅は中身なり、位置は中央」にしたいときは width: fit-content と組み合わせます。

.badge {
  width: fit-content;
  margin-inline: auto;
}

実測(#12):中身の幅 112px に縮み、L=94 / R=94。inline-block にして親に text-align: center を書く方法(#14)でも同じように中央(L=100 / R=100)になりますが、inline-block は文字と同じ「行の中の要素」として扱われ、親の text-align や line-height の影響を受けます。ブロックのまま扱える fit-content のほうが意図が読みやすいです。

画像を横中央にする

img は初期状態で inline 要素なので、display: block にしてから margin-inline: auto を使います。

img.center {
  display: block;
  margin-inline: auto;
}

実測(#13):L=100 / R=100。親に text-align: center を書く方法でも中央になります。


縦の中央寄せ

ブロック要素のまま縦中央にする(align-content: center)

親が普通のブロック要素でも、align-content: center で中身を縦中央に寄せられます。 以前はフレックス・グリッドでしか効きませんでしたが、ブロックコンテナへの対応が Chrome 123・Firefox 125・Safari 17.4(2024年)でそろい、主要ブラウザで使えるようになりました。MDN の align-content ページでも「適用対象:ブロックコンテナ、段組みコンテナ、フレックスコンテナ」と記載されています。

<div class="parent">
  <div class="child"></div>
</div>
.parent {
  height: 200px;           /* 縦の余白を作るため高さが必要 */
  align-content: center;   /* 縦中央 */
}
.child {
  width: 100px;
  height: 60px;
  margin-inline: auto;     /* 横中央 */
}

実測(#7):L=100 / R=100 / T=70 / B=70。レイアウト方式(display)を変えないので、子の幅やマージンの相殺など、ブロック要素のふるまいをそのまま保てます。 古いブラウザにも対応が必要な場合は、次の Flexbox / Grid を使います。

1行のテキストを縦中央にする(line-height)

1行と決まっているテキストなら、line-height を親の高さと同じにすると縦中央になります。

.label {
  height: 200px;
  line-height: 200px;
  text-align: center;
}

実測(#10):T=91 / B=92。ただし2行になると行の高さも2倍になり、はみ出します(後述のチェックリスト参照)。

表のセルで縦中央にする(vertical-align: middle)

vertical-align が縦中央に効くのは、表のセル(td / display: table-cell)と inline 要素の行内の位置合わせだけです。

.cell {
  display: table-cell;
  width: 300px;
  height: 200px;
  vertical-align: middle;
  text-align: center;
}

実測(#11):L=94 / R=94 / T=91 / B=92。


上下左右の中央寄せ

Grid の place-items: center(いちばん短い)

親に2行書くだけで、子のサイズを知らなくても上下左右の中央になります。 place-items は align-items(縦)と justify-items(横)をまとめて書くショートハンドです。

<div class="parent">
  <div class="child"></div>
</div>
.parent {
  display: grid;
  place-items: center;
  height: 200px;
}

実測(#5):L=100 / R=100 / T=70 / B=70。

place-items と place-content の違い(子が複数のとき)

子が1つなら同じ結果ですが、子が複数あると並び方が変わります。 100×40px の子を2つ入れて測りました。

.items   { display: grid; place-items: center; }   /* 各セルの中で中央 */
.content { display: grid; place-content: center; } /* 行のかたまりごと中央 */
設定 1つ目の子 T / B 2つ目の子 T / B 見た目
place-items: center 30 / 130 130 / 30 高さを2等分した行の、それぞれ中央(間が空く)
place-content: center 60 / 100 100 / 60 2つがくっついて、かたまりが中央

「複数の要素をひとまとめに中央」なら place-content、「各マスの中で中央」なら place-items と覚えると迷いません。

Flexbox の justify-content + align-items

横に並べる要素を中央に集めたいときは Flexbox が自然です。 justify-content が主軸(初期値は横)、align-items が交差軸(初期値は縦)を担当します。

.parent {
  display: flex;
  justify-content: center; /* 横 */
  align-items: center;     /* 縦 */
  height: 200px;
}

実測(#3):L=100 / R=100 / T=70 / B=70。

flex-direction: column にすると軸が入れ替わり、justify-content が縦、align-items が横を担当します(#15、同じく 100/100/70/70)。

Flexbox で子に margin: auto

親を flex にすれば、子の margin: auto が上下左右すべてに効きます。 通常のブロックでは上下の auto は 0 扱いですが、flex アイテムでは余った空間を均等に分けます。

.parent { display: flex; height: 200px; }
.child  { margin: auto; }

実測(#4):L=100 / R=100 / T=70 / B=70。

position: absolute + inset: 0 + margin: auto

重ねて配置する要素は、inset: 0(上下左右0)と margin: auto の組み合わせで中央になります。 子に幅と高さが必要です。

.parent {
  position: relative;  /* 基準にする */
}
.child {
  position: absolute;
  inset: 0;            /* top/right/bottom/left: 0 のショートハンド */
  margin: auto;
  width: 100px;
  height: 60px;
}

実測(#8):L=100 / R=100 / T=70 / B=70。

position: absolute + transform: translate(-50%, -50%)

子の幅・高さが決まっていないときは、top/left: 50% で左上の角を中央に置き、translate(-50%, -50%) で自分の半分だけ戻します。

.parent { position: relative; }
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

実測(#9):L=100 / R=100 / T=70 / B=70。translate の % は「親」ではなく「自分自身」のサイズ基準なので、中身の大きさが変わっても中央に保たれます。

画面中央のモーダルを作る

ブラウザ標準の <dialog> は、showModal() で開くと既定のスタイルで画面中央に表示されます。

<dialog id="dlg">
  <p>保存しますか?</p>
  <form method="dialog"><button>閉じる</button></form>
</dialog>
<button onclick="document.getElementById('dlg').showModal()">開く</button>

実測(200×100 の dialog、ビューポート 800×600):L=300 / R=300 / T=250 / B=250。

自作する場合は、背景を画面いっぱいに固定して grid で中央にします。

.overlay {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgb(0 0 0 / 0.4);
}
.modal {
  width: 320px;
  height: 180px;
  background: #fff;
}

実測(800×600 の画面):.modal の位置は left 240 / top 210 で、(800−320)÷2=240、(600−180)÷2=210 と一致しました。


中央寄せが効かないときのチェックリスト

「効かない」の多くは、書く場所(親か子か)・要素の種類・高さの3つで説明できます。 以下はすべて実際に描画して確認した結果です。

# 症状 原因 実測(直す前) 直し方
F1 span に margin: 0 auto を書いても動かない inline 要素の左右 margin auto は 0 扱い L=0 / R=164.8 親に text-align: center、または display: block; width: fit-content
F2 ブロックに margin: auto を書いても縦が中央にならない 通常のブロックでは上下の auto は 0 T=0 / B=140 親を flex / grid にする、または親に align-content: center
F3 align-items: center を書いても縦中央に見えない 親に高さがなく、親=子の高さ(余白が0) 親の高さ 60px、T=0 / B=0 親に height や min-height を指定する
F4 height: 100% にしたのに縦中央にならない 親の親に高さがないと % の高さは auto 扱い 親の高さ 60px、T=0 / B=0 祖先に高さを指定する、または min-height: 100dvh など絶対的な値を使う
F5 親に text-align: center を書いても div が中央に来ない text-align が動かすのは中の文字・inline 要素だけ L=0 / R=200 子に margin-inline: auto
F6 inset: 0; margin: auto が親の中央にならない 親に position: relative がない 画面(初期包含ブロック)の中央 left 350 / top 270 に配置 親に position: relative
F7 div に vertical-align: middle が効かない ブロック要素には効かない(表のセルと inline のみ) T=0 / B=140 flex / grid / align-content を使う
F8 中央から右下にずれる top/left: 50% だけで transform を忘れた L=150 / R=50 / T=100 / B=40 transform: translate(-50%, -50%) を追加
F9 文字が2行になると大きくはみ出す line-height: 200px が2行ぶん(400px)になる 文字の高さ 217px、B=−108 複数行の可能性があるなら align-content: center や grid を使う
F10 inset: 0; margin: auto で子が親いっぱいに広がる 子に幅・高さがない 300×200(親と同じ) width / height(または fit-content)を指定

F3:親に高さがない(直す前と後)

縦中央は「縦に余った空間」を分ける仕組みなので、親に高さがないと分ける余白がありません。

/* 直す前:親の高さは中身なり(60px)で、縦中央の効果が見えない */
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 直した後:高さを与える */
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;   /* 画面全体なら min-height: 100dvh; */
}

画面全体の中央に置きたいときは、height: 100% を祖先すべてに書くより min-height: 100dvh のほうが確実です(dvh はスマホのアドレスバーの出入りに合わせて変わる画面の高さの単位)。

子が親より大きいときは safe center

Flexbox の justify-content: center は、子が親より大きいと左右に均等にはみ出します。 左側にはみ出した部分はスクロールしても見えません。幅400px(縮まない設定)の子を幅300pxの親に入れて測りました。

設定 L R 結果
justify-content: center −50 −50 左に50pxはみ出す(スクロールで戻れない)
justify-content: safe center 0 −100 左端をそろえ、右にだけはみ出す
子に margin: auto 0 −100 safe center と同じ
.parent {
  display: flex;
  justify-content: safe center; /* 入りきらないときは先頭寄せに切り替わる */
  align-items: center;
}

横スクロールするリストや、画面幅によって中身があふれるヘッダーでは safe center か margin: auto を選ぶと安心です。


方法ごとの比較表

方法 書く場所 子のサイズ指定 他の要素への影響 向いている場面
text-align: center 親 不要 なし 文字・アイコン・inline-block
margin-inline: auto 子 幅が必要 なし 幅を決めた箱、記事本文の幅
align-content: center(ブロック) 親 不要 なし(displayを変えない) 既存レイアウトに縦中央だけ足す
Flexbox 親 不要 子が flex アイテムになる 横・縦に並べて中央
Grid place-items 親 不要 子が grid アイテムになる 1つの要素を上下左右中央
Grid place-content 親 不要 同上 複数要素をまとめて中央
inset: 0; margin: auto 子(+親に relative) 幅・高さが必要 通常の流れから外れる 重ねて置くバッジ・ローディング
translate(-50%, -50%) 子(+親に relative) 不要 同上 サイズ不定の重ね配置
line-height 親 不要 行の高さが変わる 1行と決まったラベル
vertical-align: middle セル 不要 表レイアウト 表の中の縦位置
<dialog> ― 任意 最前面(トップレイヤー) 確認ダイアログ

よくある質問

Q. div を上下左右の中央に置く、いちばん簡単な書き方は? A. 親に display: grid; place-items: center; と、縦の余白を作るための高さ(min-height など)を書く方法です。子の幅・高さを知らなくても中央になります。実測でも L=R=100、T=B=70 でした。

Q. margin: 0 auto と margin-inline: auto は何が違いますか? A. 横書きでは結果は同じです。margin: 0 auto は上下の margin も 0 に上書きしますが、margin-inline: auto は左右(行の方向)だけを指定するので、上下の margin を別に残せます。新しく書くなら意図が明確な margin-inline: auto がおすすめです。

Q. Flexbox と Grid、中央寄せにはどちらを使えばいいですか? A. 要素が1つ(または1かたまり)なら Grid の place-items、横に並べる要素を中央に集めるなら Flexbox が書きやすいです。レイアウト全体を変えたくない場合は、ブロックのまま使える align-content: center も選べます。

Q. transform: translate(-50%, -50%) で文字がぼやけることはありますか? A. 子のサイズが奇数pxだと半ピクセルの位置になり、環境によって文字がわずかににじんで見えることがあります。気になる場合は、Grid の place-items か inset: 0; margin: auto に置き換えると、整数位置に置かれやすくなります。


まとめ

  • 中央寄せは「何を×どの方向」で決める。テキストは親に text-align、幅のある箱は子に margin-inline: auto。
  • 上下左右なら親に display: grid; place-items: center が最短。複数の子をまとめるなら place-content。
  • ブロック要素のままでも align-content: center で縦中央にできる(2024年に主要ブラウザ対応)。
  • 重ね配置は inset: 0; margin: auto(サイズ必要)か translate(-50%, -50%)(サイズ不要)。親に position: relative を忘れない。
  • 縦中央が効かないときは、まず親の高さを確認する。画面全体なら min-height: 100dvh。
  • 子が親より大きくなるなら safe center で左端の見切れを防ぐ。

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

(記載例)出典:株式会社RJC「CSS 中央寄せの方法|横・縦・上下左右の早見表と実測結果15パターン」

株式会社RJCでは、こうしたレイアウトの小さな「なぜ?」を実際に手を動かして確かめ、プロジェクトの中で仲間と共有しています。こうした知識を共有しながら、日々技術を磨いています。

株式会社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で一緒に開発しながら、 成長を楽しみませんか?