- CSS
- フロントエンド
- 技術 💻
CSS 中央寄せの方法|横・縦・上下左右の早見表と実測結果15パターン
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期連続の黒字決算。