divを水平方向、垂直方向、またはその両方で中央に配置する方法をまとめました。フレックスボックス、グリッド、margin auto、絶対配置、文字揃えのtext-align、行の高さを使うline-heightの各手法を1つのボックス上で切り替えながら、実際のCSSと、それぞれの手法がうまくいかなくなるケースを確認できます。
divを上下左右の両方向で中央に置くには、親要素にたった2行のCSSを書くだけで済みます。グリッドを使う場合は display: grid; place-items: center; と書き、フレックスボックスを使う場合は display: flex に加えて、横方向の配置を決める justify-content: center と縦方向の配置を決める align-items: center を指定します。水平方向だけを中央にしたいなら、div自体に幅を指定したうえで、左右のマージンを自動で均等に割り振る margin-inline: auto を付けます。なお、垂直方向の中央寄せが目に見えて効くためには、親要素の高さが子要素よりも大きくなっている必要があります。
要点だけ
手法と方向を選ぶとデモのボックスが実際に動き、親要素と子要素それぞれのCSSが書き出され、その手法がうまくいかなくなるケースについての注記も表示されます。既存のコードで今もよく見かける古い手法も含めて、全部で7つのテクニックを取り上げ、最後にどの手法を選べばよいかを判断するための表を載せています。
多くの場合、原因は親要素に余分な高さがないことです。ブロック要素の高さは中身の量と同じになるため、そもそも中央に寄せるための余白がありません。親要素に高さ(height)や最小の高さ(min-height、たとえば画面全体なら100dvh)を指定するか、より背の高いフレックスボックスやグリッドのレイアウトの中で親要素を引き伸ばしましょう。
親要素に display: grid; place-items: center; と指定するのが最も短い方法です。これだけで子要素が上下左右どちらの方向にも中央へ配置され、子要素がどんな大きさでも同じように機能し、子要素の側に幅や高さを指定する必要もありません。
まず、bodyまたはラッパー要素の高さを、少なくとも画面(ビューポート)と同じ高さにします。具体的には min-height: 100dvh; display: grid; place-items: center; と指定します。一方、ページの上に浮かんで表示されるモーダルの場合は、幅と高さをあらかじめ決めたうえで position: fixed; inset: 0; margin: auto; を使うか、何もしなくても自動的に画面中央へ配置されるブラウザー標準のdialog要素を使うのが手軽です。
はい、使えます。ただし対象は、親要素より狭い幅を持つブロックを水平方向に中央寄せする場合です。margin-inline: autoはその書き方を現代的な論理プロパティで表したもので、左右だけに作用し、上下のマージンには一切影響を与えません。
親要素に、フレックスボックス系なら flex items-center justify-center を、グリッド系なら grid place-items-center を付け、さらに h-screen や min-h-dvh などのクラスで親要素自体に高さを与えます。ブロックを水平方向だけ中央寄せしたい場合は、子要素の側に mx-auto を付け、あわせて幅または最大幅を指定するクラスを追加します。
用途ごとの手法
実際のページでは、外側のラッパー要素にmin-height: 100dvhを指定して画面全体の高さを確保します。ここではデモの枠の中に収まるよう、代わりに固定の高さを使っています。
inset: 0とmargin: autoを組み合わせると、大きさが決まった子要素をtransformを使わずに中央へ置けるため、輪郭がぼやけずくっきりしたまま表示されます。
フレックスボックスの子要素に自動のマージンを付けると、余ったスペースをすべて吸収します。そのため、メニューとカートが左右の端に残ったまま、ロゴだけがバーの真ん中に配置されます。
垂直方向の中央寄せを効かせるには、親要素の高さが子要素よりも大きくなっている必要があります。また、flex-direction: columnを指定して並びを縦向きにすると、横方向と縦方向を担当する2つのプロパティの役割がそっくり入れ替わる点にも注意してください。
子要素が複数あると、それぞれが別々の行として縦に積み重なり、各行の中で個別に中央へ置かれます。その結果、ひとかたまりにまとまらず、上下に間隔を空けて広がってしまいます。まとめて中央に置きたいときは、全体を1つの要素で包みましょう。
通常のブロックの流れの中では、水平方向にしか中央寄せができません。しかもそれは、子要素の幅が親要素の幅より小さい場合に限られます。ただし、親要素がフレックスボックスやグリッドの場合は、margin: autoだけで上下左右どちらにも中央寄せできます。
子要素が通常の流れから外れてしまうため、親要素は子要素の大きさに合わせて広がらなくなります。また、半ピクセル単位のずれによって文字がぼやけて見えることがあり、さらにtransformを指定したことで、子要素が包含ブロックであると同時に新しい重なりの基準(スタッキングコンテキスト)にもなります。
中央寄せしたい方向について、子要素に明示的なサイズを指定する必要があります。指定しないと、inset: 0によって子要素が親要素の大きさいっぱいに引き伸ばされるだけで終わります。なお、現在のブラウザーであれば、内容に合わせたfit-contentの幅を使うこともできます。
動かせるのは、文字や画像、インラインブロックのボックスといったインラインの内容だけです。通常のブロック要素であるdivそのものには効果がなく、しかも子要素の中にある文字にまで中央揃えが受け継がれてしまいます。
文字が折り返して2行目にかかった時点で表示が崩れてしまううえ、高さの値を2か所に直接書き込まなければなりません。1行だけのバッジやボタンには使えますが、それ以外の用途には向きません。
方向
中央寄せ
手法
親要素(破線)と子要素(青)
子ボックス
この手法では、選んだ方向の中央寄せはできません。ボックスは、その方向の指定がない場合に実際に表示される位置を示しています。
CSSをコピー
クラスをコピー
うまくいかない場合:
無料で始める · クレジットカード不要