結論から
div を親の中で上下左右の中央に寄せるには、親を grid にして内容を中央に置きます:
.parent {
display: grid;
place-items: center;
min-height: 200px; /* the parent needs room to center in */
}
子要素のサイズに関係なく動き、子要素には何も指定する必要がありません。下に 6 つの方法を並べました。それぞれのボックスは描画後に自分を測り、自分の中心が親の中心からどれだけずれているかを表示します:
6 つとも両方向で 0px と表示されます (ステージの 1px の border は全辺同じなので、中心はずれません)。ボックスの幅や文字を変えてもう一度実行してみてください。固定のサイズに頼らない方法は 0 のままです。
どの方法を使うか
| 方法 | 中央に寄せる方向 | 子要素に固定サイズが必要か | 向いている場面 |
|---|---|---|---|
grid の place-items: center | 上下左右 | いいえ | 基本の選択肢: ボックスの中の 1 つの子要素 |
flexbox の justify-content と align-items | 上下左右 | いいえ | 行や列に並んだ要素を、まとめて中央に寄せる |
flex や grid の親の中での margin: auto | 上下左右 | いいえ | 兄弟要素は別の配置のまま、1 つだけ中央に寄せる |
margin: 0 auto | 横方向のみ | width か max-width | 通常のフローの中のページのコンテナ、記事、フォーム |
absolute と translate(-50%, -50%) | 上下左右 | いいえ | ほかの内容の上に重ねるオーバーレイ、バッジ、モーダル |
absolute と inset: 0; margin: auto | 上下左右 | 必要 (幅と高さ) | 固定サイズのダイアログ |
block に align-content: center | 縦方向 | いいえ | 親の display を変えずに縦方向の中央に寄せる |
方法 1: flexbox
flexbox は 2 つのプロパティで 2 つの軸の中央に寄せます。justify-content が主軸 (横並びなら横方向)、align-items が交差軸を担当します:
子要素が複数あると、flexbox はそれらを横に並べたまま、まとめて中央に寄せます。ここは grid より優れている点で、grid だと 3 つの要素は中央の 1 列に縦に積まれます。配置の値はすべて justify-content のページ で解説しています。
方法 2: grid
place-items: center は align-items: center と justify-items: center をまとめたショートハンドです。子要素が 1 つの grid コンテナでは、その子要素を両方向の中央に寄せます:
height ではなく min-height にしているので、カードが 180px より高くなってもカードがはみ出さず、親が大きくなります。
方法 3: margin: 0 auto (横方向)
コンテナより幅の狭い block 要素は、左右の margin を auto にすると横方向の中央に寄せられます。ブラウザが余白を左右に均等に分けます:
2 つ目のボックスは幅いっぱいに広がっているので、余白がなく何も動きません。margin: 0 auto が「効かない」ときの原因はたいていこれです。また、通常のフローでは横方向にしか中央に寄せられず、縦方向の auto の margin は 0 になります。ただし flex や grid の親の中では、margin: auto で両方向の中央に寄せられます。上の比較の 3 つ目のボックスがそれです。
方法 4: absolute と transform
要素をほかの内容の上に重ねる必要があるとき (写真の上のバッジ、ページの上のモーダル) は、absolute で 50% の位置に置き、自分のサイズの半分だけ戻します:
top: 50%; left: 50% で要素の左上の角が中央に来ます。translate() のパーセントは要素自身のサイズが基準なので、-50% で幅と高さがいくつでも、その半分だけ戻ります。親は位置指定 (position: relative) されている必要があり、そうでないと要素はページの中央に寄ります。位置指定については position のページ で解説しています。
サイズがわかっている要素向けの変形もあります: position: absolute; inset: 0; margin: auto; に width と height を加えます。auto の margin が 4 辺の余白を分け合います。
方法 5: 普通の block に align-content
align-content: center は、flex や grid だけでなく普通の block コンテナでも効くようになりました。子要素の配置のしかたを変えずに、内容を縦方向の中央に寄せます:
.parent {
min-height: 200px;
align-content: center; /* vertical centering, still display: block */
}
.child {
max-width: 300px;
margin-inline: auto; /* horizontal centering */
}
現在の Chrome、Firefox、Safari で使えます。古いブラウザでは無視されるので、それらに対応する必要があれば grid を使いましょう。
画面全体の中央に寄せる
スクロールに関係なくダイアログをビューポートの中央に置くには、画面全体を覆う fixed のレイヤーと grid を組み合わせます:
.overlay {
position: fixed;
inset: 0; /* covers the viewport */
display: grid;
place-items: center;
background: rgb(0 0 0 / 50%);
}
ページ全体の内容を縦方向の中央に寄せるなら、親には 100vh ではなく min-height: 100dvh を使います。スマートフォンでは 100vh がブラウザのツールバーの裏の領域まで含むので、「中央」が低すぎる位置になります。
文字の中央揃えは別の作業
ここまでの方法はすべてボックスを中央に寄せるものです。ボックスの中の文字を中央揃えにするには、ボックスに text-align: center を指定します。HTML で文字を中央揃えにするページ で解説しています。多くの場合は両方が必要です。grid でカードを中央に寄せ、text-align でその中の行を中央揃えにします。
よくある間違い
- 親に高さがない。 縦方向の中央寄せには余白が必要です。内容に合わせて縮む親には余白がありません。
- 幅いっぱいの block に
margin: 0 auto。 先にwidthかmax-widthを指定しましょう。 - 通常のフローで
margin: autoを使って縦方向の中央に寄せようとする。 そこでは縦の auto の margin は 0 です。flex か grid を使いましょう。 - 位置指定された親なしに absolute で中央に寄せる。 要素はボックスではなくページの中央に寄ります。
- 子要素に
align-items: centerを指定する。 配置のプロパティは親 (flex や grid のコンテナ) に書きます。例外はmargin: autoとalign-selfです。 - block を中央に寄せるのに
text-align: centerを使う。 これはインラインの内容 (文字、画像、inline-block の子要素) を中央に揃えるもので、block の子要素は動きません。
よくある質問
div を上下左右の中央に寄せるには?
親を grid にして内容を中央に置きます: .parent { display: grid; place-items: center; }。flexbox なら display: flex; justify-content: center; align-items: center; です。どちらの場合も、親に div より大きい高さが必要です。
div を横方向だけ中央に寄せるには?
幅を指定し、左右の margin を auto にします: .box { width: 300px; margin: 0 auto; } (レスポンシブな要素なら max-width)。論理プロパティの margin-inline: auto も同じ意味です。
margin: 0 auto で div が中央に寄らないのはなぜですか?
div にコンテナより小さい幅がないので、分け合う余白がないからです (block は初期状態で幅いっぱいに広がります)。width か max-width を指定しましょう。inline 要素では効かず、通常のフローでは縦方向の中央寄せにもなりません。
div が縦方向の中央に寄らないのはなぜですか?
親の高さが内容と同じしかないので、中央に寄せるための余白がないからです。親に高さ (または min-height) を与えてから、grid か flexbox で中央に寄せます。
div を中央に寄せる一番簡単な方法は?
親に display: grid; place-items: center; を指定することです。宣言 2 つで両方向に、子要素のサイズに関係なく中央に寄せられます。親がほかの要素も横に並べるなら flexbox を使います。
div の中の文字を中央揃えにするには?
文字とインラインの内容には、div に text-align: center を使います。div 自体を中央に寄せることと、その中の文字を中央揃えにすることは別の作業です。