CSSで子要素を中央揃えにする方法をまとめてみる

いろいろありますよね。
どれが正解というわけでもないので、それぞれの実装方法を頭に入れておいて案件によって使いやすい方法を引き出せるよう、整理しておきたいと思います。

ベース:何もしない状態

親要素をdiv.container-cとします。これはこの記事内で共通です。

div.container-c {
  border: 1px solid #B9B2A2;
  border-radius: 10px;
  width: 100%;
  height: 250px;
  margin-bottom: 16px;
}

そして、これを基本的なCSSとします。

子要素がインライン要素の場合

spanタグ

子要素はspanでテキストを置きます。

<div class="container-c">
  <span>Center</span>
</div>
Demo
Center
imgタグ

こちらは子要素にimgを置きます。

<div class="container-c">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

CSSで位置に関する記述は何もしていないデフォルトの状態ですので、普通に左寄せ上寄せになっていますね。

子要素がブロック要素の場合

divタグ

子要素はdiv.childとして

<div class="container-c">
  <div class="child"></div>
</div>
div.child {
  background: #EECE34;
  width: 125px;
  height: 125px;
  border-radius: 50%;
}

とします。

Demo
imgタグ(ブロック)

子要素imgの方には、CSSでdisplay: block;を当ててブロック要素にします。
(編集が楽なので、ベースとなる箇所以外は外部CSSで記述せずにstyleで記述します)

<div class="container-c">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

こちらも位置に関する指定はしてないので、普通に左寄せ上寄せになっています。

左右中央揃え

まずは普通に左右中央揃えを。
簡単でしょ? text-align: center;でしょ? となるかもしれませんが、text-align: center;しか知らないと早々につまづくので、すっ飛ばさないでちゃんと整理します。

子要素がインライン要素の場合

前述のベースを使用します。ベースとなる箇所以外は外部CSSで記述せずにstyleで記述しています。

text-align: center;

親要素にtext-align: center;をかけます。
子要素がインライン要素であればtext-align: center;が効いて左右中央揃えになります。
text-align: center;子要素がブロック要素の場合には効かないので注意してください。

spanタグ
<div class="container-c" style="text-align: center;">
  <span>Center</span>
</div>
Demo
Center
imgタグ(インライン)
<div class="container-c" style="text-align: center;">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン"></img>
</div>
Demo
ロボットアイコン

Flexbox

Flexboxでも左右中央揃えにしてみましょう。こちらも親要素にCSSを記述していきます。
Flexboxを使いたいときはまずdisplay: flex;、子要素を左右中央に持ってくるためにさらにjustify-content: center;を加えます。
(Flexboxの場合は、子要素がインライン要素でもブロック要素でも問題ありません)

spanタグ
<div class="container-c" style="display: flex; justify-content: center;">
  <span>Center</span>
</div>
Demo
Center
imgタグ(インライン)
<div class="container-c" style="display: flex; justify-content: center;">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

このやり方をして画像が親要素いっぱい縦に伸びてしまった場合、例えばBootstrapのCSSで記事内のimgに対してheight: auto;が設定されているのが悪影響を及ぼしていることがあります。CSSで高さ指定し返して打ち勝ちましょう!

テスト:子要素が複数のとき
<div class="container-c d-flex justify-content-center">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
ロボットアイコン

ここは問題なさそうですね。

CSS Grid(IE11非対応)

私が食わず嫌いしているCSS Gridレイアウトですが、この機会に触ってみます。「子要素を真ん中に置く」とシンプルに考えると大丈夫かな?
CSS Gridレイアウトについて詳しい概要は以下を参照してください。


親要素にdisplay: grid;を、子要素を左右中央に持ってくるためにさらにjustify-content: center;を加えます。Gridでもjustify-content: center;を使えるんですね。

IE11でCSS Gridレイアウトを使う場合、注意点があります。

  • ベンダープレフィックスを使う必要あり。
  • justify-contentalign-contentが使用できないため、子要素に対して位置を指定する
  • 子要素がインライン要素の場合は使用できない。

下記サイトが詳しいのでご参照ください。

spanタグ
<div class="container-c" style="display: grid;  justify-content: center;">
  <span>Center</span>
</div>
Demo
Center
imgタグ(インライン)
<div class="container-c" style="display: grid; justify-content: center;">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

なった!(IE11ではなってません)

テスト:子要素が複数のとき
<div class="container-c" style="display: grid; justify-content: center;">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコンロボットアイコン

そう来るか!

<div class="container-c" style="display: grid; justify-content: center;">
  <div>
    <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
    <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
  </div>
</div>
Demo
ロボットアイコンロボットアイコン

divを入れ子にして中の子要素を包んだら左右中央に来ました。

子要素がブロック要素の場合

前述のベースを使用します。ベースとなる箇所以外は外部CSSで記述せずにstyleで記述しています。

margin-left: auto; margin-right: auto;

皆が大好きmargin: auto;です。
子要素のmargin-left、margin-rightが共にautoの場合に、auto = (親要素のwidth - 子要素のwidth) / 2となるため左右に等しくmarginが設定され真ん中に寄ることになります。

divタグ
<div class="container-c">
  <div class="child" style="margin-left: auto; margin-right: auto;"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c">
  <img src="/images/icon-robot.png" style="display: block; margin-left: auto; margin-right: auto;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
テスト:子要素が複数のとき
<div class="container-c">
  <div style="width: 250px; display: flex; margin-left: auto; margin-right: auto;">
    <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
    <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
  </div>
</div>
Demo
ロボットアイコンロボットアイコン

子要素を包む入れ子のdivにwidth指定をしつつ、display: flex; margin-left: auto; margin-right: auto;を当てる……面倒くさい。。

Flexbox

Flexboxの場合は子要素がインライン要素でもブロック要素でも変わりません。

divタグ
<div class="container-c" style="display: flex; justify-content: center;">
  <div class="child"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="display: flex; justify-content: center;">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
テスト:子要素が複数のとき
<div class="container-c" style="display: flex; justify-content: center;">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
ロボットアイコン

CSS Grid(IE11非対応)

こちらも子要素がインライン要素でもブロック要素でも変わらないようです。

divタグ
<div class="container-c" style="display: grid; justify-content: center;">
  <div class="child"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="display: grid; justify-content: center;">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

position: absolute;

最近よく使われてると思われるのがこちら。
親要素にまずposition: relative;をかけて基準とし、子要素にposition: absolute;で位置を調整できるようにします。left: 50%;で親要素の幅の半分の位置に持ってきます。このままでは中央揃えではなく中央の位置に頭が来ていますので、さらにtransform: translateX(-50%);で子要素の幅の半分の値を水平方向で戻すことで左右中央にピッタリ位置します。

以前の記述の仕方ではmargin-left: -62px;のように、こちらで子要素の幅を把握して半分の値をネガティブマージンでかけていました。transform: translateX(-50%);を使うと子要素の幅を把握する必要の無いし、なにより他の場所でも使い回せる!という万能っぷり。

インライン要素に対してposition: absolute;を当てると、イレギュラーなのか挙動がちょっと複雑になるようです。使いたい場合は、display: block;を当てる方が安心だと思います。
positionプロパティに関しては以下の記事が詳しいです。

divタグ
<div class="container-c" style="position: relative;">
  <div class="child" style="position: absolute; left:50%; transform: translateX(-50%);"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="position: relative;">
  <img src="/images/icon-robot.png" style="position: absolute; left:50%; transform: translateX(-50%);" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
テスト:子要素が複数のとき
<div class="container-c" style="position: relative;">
  <div style="display: flex; position: absolute; left: 50%; transform: translateX(-50%);">
    <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
    <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
  </div>
</div>
Demo
ロボットアイコン
ロボットアイコン

divを入れ子にして、display: flex;で左右中央に来ました。
divを入れ子にしたときの寄せ方はバリエーションがメッチャありそうなので、今回はあまり深追いしないことにします。

このposition指定を使うことで、ただのセンタリングではなく親要素をはみ出して子要素を配置することもできます。


上下中央揃え

左右ができたので、今度は上下で中央揃えにしてみましょう。
基本的に水平座標への指定を垂直座標に置き換える形ですね。

子要素がインライン要素の場合

padding-topを指定して上下中央に持っていくやり方は省略します。

Flexbox

左右中央にするにはjustify-content: center;でしたが、上下中央の場合はalign-items: center;をあてます。

spanタグ
<div class="container-c" style="display: flex; align-items: center;">
  <span>Center</span>
</div>
Demo
Center
imgタグ(インライン)
<div class="container-c" style="display: flex; align-items: center;">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
テスト:子要素が複数のとき
<div class="container-c" style="display: flex; align-items: center;">
  <span>Center</span>
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
Center
ロボットアイコン

ちゃんと上下中央の位置で揃ってますね。

CSS Grid

同じくalign-items: center;を当てます。

spanタグ
<div class="container-c" style="display: grid; align-items: center;">
  <span>Center</span>
</div>
Demo
Center
imgタグ(インライン)
<div class="container-c" style="display: grid; align-items: center;">
  <img src="/images/icon-robot.png" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

配置する子要素が1つだと問題なさそうですね。

子要素がブロック要素の場合

Flexbox

Flexboxなので、子要素がインライン要素の場合と同様です。

divタグ
<div class="container-c" style="display: flex; align-items: center;">
  <div class="child"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="display: flex; align-items: center;">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン
テスト:子要素が複数のとき
<div class="container-c" style="display: flex; align-items: center;">
  <div class="child"></div>
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo

ロボットアイコン

CSS Grid(IE11非対応)

CSS Gridなので、子要素がインライン要素の場合と同様です。

divタグ
<div class="container-c" style="display: grid; align-items: center;">
  <div class="child"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="display: grid; align-items: center;">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

position: absolute;

水平座標がX、垂直座標がYなので、左右中央揃えで使用したtransform: translateX(-50%);transform: translateY(-50%);にし、left: 50%;top: 50%;にすれば上下中央揃えになりますね。

divタグ
<div class="container-c" style="position: relative;">
  <div class="child" style="position: absolute; top: 50%; transform: translateY(-50%);"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="position: relative;">
  <img src="/images/icon-robot.png" style="display: block; position: absolute; top: 50%; transform: translateY(-50%);" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

上下左右中央揃え

いよいよ上下も左右も中央に揃えてみます。

子要素がインライン要素の場合

text-align: center;およびpaddingで調整するやり方は省略します。
display: block;を当てて、以下の「子要素がブロック要素の場合」の各手法でやった方がスマートだと思います。

子要素がブロック要素の場合

Flexbox

左右中央にするにはjustify-content: center;、上下中央にするにはalign-items: center;でした。そう!両方当てればいいんです。

divタグ
<div class="container-c" style="display: flex; justify-content: center; align-items: center;">
  <div class="child"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="display: flex; justify-content: center; align-items: center;">
  <img src="/images/icon-robot.png" class="d-block" width="125px" height="125px" alt="ロボットアイコン" />
</div>
Demo
ロボットアイコン
テスト:子要素が複数のとき
<div class="container-c" style="display: flex; justify-content: center; align-items: center;">
  <div class="child"></div>
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン" />
</div>
Demo

ロボットアイコン

CSS Grid(IE11非対応)

Flexboxと異なりdisplay: grid;の場合、justify-content: center;align-items: center;place-items: center;ひとまとめに記述することができます。
ただし、place-items: center;IE11非対応ですので、ブラウザ要件に注意してください。

divタグ
<div class="container-c" style="display: grid; place-items: center;">
  <div class="child"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="display: grid; place-items: center;">
  <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

position: absolute;

水平座標も垂直座標も同時に設定したい場合、transform: translate(-50%,-50%);とまとめて記述することができます。

divタグ
<div class="container-c" style="position: relative;">
  <div class="child" style="position: absolute; 
 top: 50%; left: 50%; transform: translate(-50%,-50%);"></div>
</div>
Demo
imgタグ(ブロック)
<div class="container-c" style="position: relative;">
  <img src="/images/icon-robot.png" style="display: block; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);" width="125px" height="125px" alt="ロボットアイコン">
</div>
Demo
ロボットアイコン

画像が滲んでしまっていますが、これは125px×125pxと奇数値で画像を書き出したせいですね。要素の-50%戻るため割り切れた方が良さそうです。地味なところですが、以後注意します。

テスト:子要素が複数のとき
<div class="container-c" style="position: relative;">
  <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);">
    <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
    <img src="/images/icon-robot.png" style="display: block;" width="125px" height="125px" alt="ロボットアイコン">
  </div>
</div>
Demo
ロボットアイコン
ロボットアイコン

divを入れ子にして、そちらにposition: absolute;や位置指定の記述をします。
Wordpressの仕様で勝手に画像の間にbrタグが入ってしまっていますが、上下左右中央に寄っています。

使用アイコン

突然宣伝です。
この記事で使用したロボットアイコンはStock Photo各社で販売中です!
6体のロボットバリエーションがセットでもちろんベクターもあります。フルカラーバージョンもご用意してますので、お気に召しましたら。