この記事では、HTMLとCSSで要素を中央配置する9つの方法をパターン別に紹介していきます。縦方向と横方向それぞれの方法をまとめます。また「中央寄せできない」というときの対処法もパターン別にまとめておきます(スキップする)。

横センタリング(左右中央寄せ)

まずは、横方向に中央寄せする方法を見ていきましょう。

その1:文章を中央揃え

文章が中央揃えになる

文章を左右中央に揃えたいときは、その文章を含むブロックコンテナーにtext-align: center;を指定します。親要素に指定して継承させることもできます。

文章を中央寄せにする例

例えば、pタグに含まれる文章の場合
p {text-align: center}
とCSSで指定します。

pタグの親要素にtext-alignを指定しても、子がその値を継承すれば文字は左右中央に寄ります。ウェブページ全体の文字を真ん中に寄せたいならbody { text-align: center; }と指定できます。ただし、子自身に別のtext-alignが指定されていれば、そちらの値になります。

その2:画像を中央寄せ(左右)

画像を真ん中に配置

画像が通常のinline表示なら、文章と同じように扱うことができます。imgタグ自身ではなく、画像を含む親要素にtext-align: center;を指定します。display: block;を指定した画像の箱を移動するときは、後述のmarginなどを使います。

HTMLコード
<p class="centering-c01">
  <img src="https://saruwakakun.com/wp-content/uploads/2017/05/bdrdagd-22.jpg" alt="山と川のイラストを含む公開当時の表示画像" width="812" height="432">
</p>
CSSコード
.centering-c01 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c01 {
  margin: 0;
  text-align: center;
}

.centering-c01 img {
  display: inline;
  width: 200px;
  max-width: 100%;
  height: auto;
}
公開当時のブラウザ表示(画像)画像を真ん中に

公開当時の結果画像を保持しています。コピー用コードでは実在するこの画像を例として使っています。自分の画像へ置き換えるときはsrcとalt、実寸を変更してください。HTMLとCSSを両方コピーして使えます。

その3:blockの要素を中央寄せ

ブロックの要素を中央寄せ

ここから少し難しくなります。しかし、ここを理解しておかないと「中央寄せできない」や「text-align:centerが効かない」等とつまずくことになります。

文章を中央寄せにする例

上で紹介した例では、pタグの中の文章を真ん中に寄せました。しかし、p要素全体は左に寄ったままです。

p要素自体を真ん中に寄せたい

もし、p要素全体を中央配置したい場合にはどうすれば良いのでしょうか。

text-alignではブロックの箱自体を中央寄せできない

pタグの親要素(例えばdiv)に対して、text-align:centerを指定しても、p全体は中央配置になりません。

公開当時の図です。「効かない」は箱自体の位置を指します。
text-alignではブロックの箱自体を中央配置できない例

text-alignは、pタグなどのブロックコンテナーに適用され、その中の文章やinline表示の画像を揃えます。ブロックの箱自体を、親の中で移動させる指定ではありません。図の「効かない」は箱自体の位置についての説明です。

「block(ブロック)って何?」という方は、下の記事に目を通すとサクッと理解できるはずです。

あわせて読みたい【CSS】displayの使い方を総まとめ!inlineやblockの違いは?

blockの要素って何?

上の記事に書かれていますが、<p>、<div>、<h1>〜<h6>などには、通常ブラウザの既定スタイルでdisplay: block;が指定されています。text-alignでは、これらの中身の「文章」やinline表示の「画像」を中央揃えにできますが、箱自体を真ん中に寄せることはできません。

marginでセンタリング

「じゃあどうするのか」ということですが、marginプロパティを使えば簡単です。

marginプロパティで横方向にセンタリング

通常フローのdisplay: block;の箱では、幅を決めて左右に余りがあるとき、margin-leftとmargin-rightをどちらもautoにすると水平方向に中央寄せできます。幅がautoで横いっぱいに広がる箱や、包含ブロックより大きい箱では同じ結果になりません。

「右の余白も左の余白も自動で決まるようにすれば、真ん中に配置される」というわけですね。「marginって何ぞ?」という方は下の記事を読んでみてください。イチから解説しています。

あわせて読みたいCSSのmarginとは?paddingとは?余白の指定方法まとめ

実際にやってみる

試しにdivタグを真ん中に寄せてみたいと思います。そのままの大きさでは、横いっぱいに広がってしまうのでwidthで幅を指定します。

HTMLコード
<div class="centering-c02">例文</div>
CSSコード
.centering-c02 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c02 {
  margin: 10px auto;
  width: 50px;
  background: orange;
}
ブラウザ表示:marginによる左右中央寄せ

中央に寄っているのが分かるかと思います。説明する必要もないかもしれませんがmargin: 10px autoというのは省略した書き方で「上下の値は10px、左右の値はauto」という意味になります。

包含ブロックの真ん中であることに注意

親要素の中でのセンタリングとなる

ここで注意したいのが、あくまで「包含ブロックの幅を基準に中央寄せとなっている」ということです。この図のように通常フローで親がdivなら、その親の内容領域が基準になります。画面全体を基準にするとは限りません。

親要素が左に寄ってることも

例えば、親要素が左に寄ってたら、その分だけ左に寄ることになるわけですね。

親要素の幅までしっかり確認する

「画面の真ん中に配置したいのに、基準となる包含ブロックの幅が思った以上に小さいため左に寄ってしまう」というようなことはよくあります。この図では親の幅がその基準です。

親要素の幅を指定することでmarginプロパティで中央寄せができる

そんなときは必要に応じて、基準となる親の幅も指定するようにしましょう。 通常フローのblockは幅autoなら利用可能な幅に広がるため、常に親の幅を指定する必要があるわけではありません。表やflex itemなどでは幅の決まり方も違います。図のwidth: 100%;を使う場合も、余白やpadding、box-sizingを含めた実際の幅を確認しましょう。

親要素も中央寄せする

もしかすると「親要素自体を中央配置にする必要がある」なんてこともあるかもしれません。実際の表示を見ながら方法を考えるのが良いですね。

親がinlineの場合は包含ブロックと幅指定を確認

margin: 0 auto;で箱を中央配置したいときは、箱のdisplayと包含ブロックを確認します。display:inlineの解説の通り、aやspanなど非置換のinlineにはwidthが適用されません。画像などの置換要素にはこの説明をそのまま当てはめられません。直近の親がinlineというだけで、子の中央寄せが必ず失敗するわけではありません。

通常ブラウザでinline表示になる要素:<a>、<span>など

公開当時の概念図です。inlineの親でも中央配置できる場合があります。
インラインの親要素からはみ出てしまっている

ハマりがちな例を紹介します。この旧概念図のようにaタグの中にdivを入れると、CSSではinlineの中にblockがある構造になります。匿名ボックスなどが介在し、aの背景や枠がdiv全体を囲むようには見えないこともあります。HTMLとして置けるかは周囲の内容モデルにも依存します。

公開当時の図です。inline親なら中央寄せできない、とは一般化できません。
非置換のinlineにはwidthが適用されないことを示す旧概念図

通常フローのdivの左右auto marginは、直近のinline親の幅ではなく、最も近いブロックコンテナーなどが作る包含ブロックを基準に決まります。したがって、図の「inline親だから中央寄せにならない」という断定は一般化できません。a自身にwidth: 100%;を指定しても、非置換inlineのままではそのwidthは効きません。

HTMLの内容モデルを満たすことを前提に、CSSの表示を変える例です。
aタグに対してdisplay:blockを指定

a自体を幅のある箱として扱いたいときは、図のようにdisplay: block;を指定する方法があります。通常フローでは、そのaの内容領域が子divの包含ブロックとなります。子の幅と左右の余りを確保すれば、auto marginで中央配置できます。

その4:inline-blockを活用してセンタリング

インラインブロック要素をセンタリング

display: inline-block;を指定した箱は、ブロックのように幅や高さを指定でき、親の中ではinline-levelの内容として並びます。そのため親にtext-align: center;を指定すると箱を左右中央に揃えられます。

ブロック要素をinline-blockにしてからtext-alignを指定

インラインブロックならtext-alignで左右中央寄せできる

divやpなどをinline-blockに変えると、親にtext-align: center;を指定して箱を中央配置できます。幅・高さも指定できます。aやspanなどをinline-blockにして、幅・高さを指定できるようにすることもできます。

実際にやってみましょう。

HTMLコード
<div class="centering-c03">
  <div class="centering-c03__example">例文です</div>
</div>
CSSコード
.centering-c03 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c03 {
  text-align: center;
}

.centering-c03__example {
  display: inline-block;
  width: 100px;
  background: orange;
}
ブラウザ表示:inline-blockの左右中央寄せ

↑ クラスが「centering-c03__example」のdivタグをinline-blockに変えています。text-alignは親に指定します。継承により「例文です」という中身の文も中央揃えになりますが、文を左寄せのままにしたいなら.centering-c03__example { text-align: left; }を追加します。

縦センタリング(上下中央寄せ)

次に縦方向に真ん中に寄せる方法をパターン別に紹介していきます。「横と同じようにmargin-top: auto; margin-bottom: auto;を使えば良さそう」と考えるかもしれません。しかし、通常フローの非置換blockでは上下auto marginの使用値は0となり、この方法で縦中央には寄りません。後述のFlexboxなどでは上下auto marginで中央配置できる場合もあります。ここでは1つずつ方法を見ていきましょう。

その1:ボックス内の文字を縦中央に寄せる

インライン要素の中身を縦中央に配置

親要素の中央に文字を配置する(1行の場合)

文が1行におさまる場合は「行の高さ=ボックスの高さ」とすることで、行ボックスを縦中央に配置できます(行の高さはline-heightで決めます:CSSで行高を指定する方法)。文字の見た目の中心はフォントによって多少違います。marginやpaddingでもずれるので、例ではpのmarginを0にします。例を見てみましょう。

line-heightによる行の高さを親要素の高さに合わせて1行の文字を縦中央に配置する図

この図のように「行の高さ=親要素の高さ」とします。つまり、親要素の高さ(height)が50pxなら、子要素の行高(line-height)も50pxに合わせます。

実際に見てみましょう。

HTMLコード
<div class="centering-c04">
  <p>これは例文です</p>
</div>
CSSコード
.centering-c04 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c04 {
  height: 150px;
  background: orange;
}

.centering-c04 p {
  margin: 0;
  line-height: 150px;
}
ブラウザ表示:1行のline-heightによる縦中央寄せ

↑ heightは親要素(オレンジ部分)に対して指定しています。

文章が2行以上になる場合には使えない

この方法の欠点は文章が2行以上になるとデザインが崩れてしまうことです。「行の高さ=ボックスの高さ」なのでボックスからはみ出てしまうわけですね。

HTMLコード
<div class="centering-c05">
  <p>これは例文です。<br>これは2行目です。</p>
</div>
CSSコード
.centering-c05 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c05 {
  height: 150px;
  background: orange;
}

.centering-c05 p {
  margin: 0;
  line-height: 150px;
}
ブラウザ表示:2行でline-heightがはみ出す失敗例

↑2行目がボックスからはみ出てしまっているのが分かるかと思います。文が2行以上になる場合には、少し複雑になりますがその2の方法を使いましょう。

その2:absoluteを活用して縦中央に配置

上下中央寄せ

少しだけ複雑ですが、絶対配置とtransformを組み合わせて縦中央に寄せる方法を紹介します。複数行の文章、ブロックやinlineの要素、疑似要素にも使えます。ただし、絶対配置した要素は通常フローから外れ、内容だけでは親の高さを作りません。内容が親の高さを超えるとはみ出すこともあります。

以下のようなCSSを指定すれば、親要素の上下中央に配置されるようになります。

absoluteとtop: 50%、translateY(-50%)による縦中央寄せ

この例では親にposition: relative;を指定して包含ブロックを作り、4つの指定で上下中央に配置します。position: relativeやabsoluteについては、こちらの記事が参考になるはずです。

あわせて読みたいCSSのpositionを総まとめ!absoluteやfixedの使い方は?

top: 50%;だけだと、親が作る包含ブロックの高さの半分の位置に、子の上端が来てしまいます。そこでtransform: translateY(-50%);により、子自身の参照箱の高さの半分だけ上へ移動して補正します。現在の主要ブラウザで使える標準の構文です。古い環境にも対応する必要がある場合は対象環境の対応を別途確認しましょう。

例をいくつか紹介します。

例:複数行の文章の場合

HTMLコード
<div class="centering-c06">
  <p>1行目です。<br>2行目です。</p>
</div>
CSSコード
.centering-c06 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c06 {
  position: relative;
  background: orange;
  height: 200px;
}

.centering-c06 p {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}
ブラウザ表示:複数行を絶対配置で縦中央寄せ

例:擬似要素を縦にセンタリング

擬似要素でもこの方法が使えます。

HTMLコード
<div class="centering-c07"></div>
CSSコード
.centering-c07 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c07 {
  position: relative;
  background: orange;
  height: 200px;
}

.centering-c07::before {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  content: "BOX";
  background: yellow;
}
ブラウザ表示:疑似要素を絶対配置で縦中央寄せ

黄色のBOXは::beforeのcontentによる装飾文字です。

先程とほとんど変わりませんね。

ど真ん中(中心)に配置する方法

ここまでの解説を応用すれば、簡単に「親要素のど真ん中に配置」することができます。

その1:ボックスをど真ん中に配置

縦のその2の方法で解説したabsoluteとtransform: translateを活用した方法が簡単です。

上下左右ど真ん中に寄せる方法

上の図のように、親が作る包含ブロックの上(top)から50%、左(left)から50%の位置に絶対配置します。これだけだと子の上端・左端が中心に来るため、transform: translate(-50%, -50%);で子自身の幅・高さの半分ずつ移動して補正します。

HTMLコード
<div class="centering-c08">
  <p>BOX</p>
</div>
CSSコード
.centering-c08 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c08 {
  position: relative;
  background: orange;
  height: 200px;
}

.centering-c08 p {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 50px;
  background: #fff;
  text-align: center;
}
ブラウザ表示:50pxのBOXを上下左右中央寄せ

その2:flexboxを使ってど真ん中に配置

Flexboxは、サイズの異なる要素を柔軟に並べるCSSのレイアウト機能です。現在の主要ブラウザで使える標準の構文を紹介します。古い環境も対象にする場合は、対応状況を確認しましょう。この横書き・row方向の例では、親にdisplay: flex;とjustify-content: center;を指定して主軸(横)の中央に、align-items: center;で交差軸(縦)の中央に配置します。子はflex itemになり、inline-blockに変える必要はありません。

HTMLコード
<div class="centering-c09">
  <div class="centering-c09__example">例文です</div>
</div>
CSSコード
.centering-c09 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c09 {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
  background: orange;
}

.centering-c09__example {
  width: 100px;
  background: #fff;
}
ブラウザ表示:Flexboxによる上下左右中央寄せ

応用:画像の上に配置したい場合

上と全く同じ方法で画像の上に文字を乗せる、というようなこともできます。コード例は下の記事で解説しています。

あわせて読みたい画像の上におしゃれに文字やボタンをのせる方法(CSS)

その3:円の中央に文字を配置

line-heightとtext-alignを使って、円の中央に文字を表示させることができます。ただし、文が改行するような場合に使うとデザインが崩れてしまいます。数字などシンプルなものを円で囲いたいときに使うと良いでしょう。

HTMLコード
<div class="centering-c10">11</div>
CSSコード
.centering-c10 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c10 {
  display: inline-block;
  text-align: center;
  width: 60px;
  height: 60px;
  line-height: 60px;
  border-radius: 50%;
  background: skyblue;
  color: #fff;
}
ブラウザ表示:60pxの円の中央に1行の数字

円自体を左右中央に寄せたいときは、親要素に対してtext-align:centerを指定します。

もし文が2行以上になる場合は、以下のようにposition:absoluteとtransform:translateYを使います。

HTMLコード
<div class="centering-c11">
  <p>サルワカ<br>saruwaka</p>
</div>
CSSコード
.centering-c11 {
  font: 16.15px/1.9 "Helvetica Neue", Arial, "Hiragino Kaku Gothic ProN", "Hiragino Sans", Meiryo, sans-serif;
  color: #333;
}

.centering-c11 {
  position: relative;
  text-align: center;
  background: skyblue;
  height: 100px;
  width: 100px;
  border-radius: 50%;
}

.centering-c11 p {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 0;
  width: 100px;
  text-align: center;
  line-height: 1.4;
  transform: translateY(-50%);
}
ブラウザ表示:100pxの円の中央に2行の文字

↑水色の円は親要素(.centering-c11)で作り、文字をその上に絶対配置しています。

中央寄せができないときの対処法

最後に「中央寄せができない」というときの対処法をまとめておきます。

  • text-align:centerが効かない 箱自体と中の文章・画像の配置を混同していませんか?(解説) 内容を含むブロックコンテナーに指定していますか?子のdisplayやtext-alignの上書きも確認しましょう。
  • margin: 0 autoが効かない
    対象が非置換inlineになっていませんか?(解説)
    箱の幅と包含ブロックの幅に余りがありますか?(解説)
  • position: absoluteができない
    狙った祖先が包含ブロックになっていますか?この例では親にrelativeを指定します(詳細)。

また、うまくいかないときはブラウザーの検証機能を使って「何が問題になっているか」をチェックするのが効率的です。

あわせて読みたい初心者向け!Chromeの検証機能(デベロッパーツール)の使い方

参考になれば幸いです。