CSSで中央揃えする方法

タナビーの高梨です。

みなさん、CSSで要素を中央揃えする場合、どんな方法で実現していますでしょうか。
いくつも方法があって、どうやろうか迷ったり、実装してみたけど思った通り中央揃えにならず何でか分からないけど他の方法でうまくいった、なんてことがあるんじゃないかと思います。

そこで今回、CSSによる中央揃えの方法についてまとめてみました。

左右中央揃え

左右中央揃えは割と単純ですね。

1.text-align:center

子要素がinlineの場合は、親要素にtext-align:centerを設定すればOK。

<div class="box1">
  test
</div>
.box1 {
  text-align: center;
  background-color: gray;
}

実行イメージ

実行イメージ

子要素が1つの場合は上記の通り簡単です。

では、子要素が複数の場合はどうでしょうか?

例えば

<div class="box1">
  <img src="asset/img1.png>
  <img src="asset/img2.png>
</div>

この場合も単純にtext-align:centerでOKです。

実行イメージ

2.margin:0 auto

次に子要素がblockの場合はどうでしょうか。

子要素が親要素よりも幅が小さいことが前提です。

この場合はおなじみのmagin:0 autoですね。

<div class="box1">outer
  <div class="box2">inner
  </div>
</div>
.box1 {
  width: 200px;
  height: 100px;
  background-color: red;
}

.box2 {
  width: 50%;
  background-color: yellow;
  margin: 0 auto;
}

実行イメージ

3.display: inline-block

では最後に子要素がinline-blockの場合はどうでしょうか。

結論から言うと、この場合もtext-align:centerでOKです。

<body>
<div class="box1">outer<br>
  <div class="box2">inner
  </div>
</div>
</body>
.box1 {
  background-color: red;
  text-align: center
}

.box2 {
  display: inline-block;
  background-color: yellow;
  margin: 0 auto;
}

実行イメージ

実行イメージ

逆に言えば、子要素の横幅が成り行きで良い場合は子要素にdispaly:inline-blockを設定してtext-align:centerにすれば良いことになります。

上下中央揃え

上下中央揃えは左右中央揃えより若干ややこしくなっています。

順を追って見ていきましょう。

1.vertical-align:middle

display:table-cellを設定できる場合は、vertical-align:middleで解決できます。

蛇足ですが、設定値はmiddleです。centerではありません。何で効かないかと思ってよく見たらcenterになっていた、ということがよくありました。

<body>
<div class="box1">box1
</div>
.box1 {
  display: table-cell;
  width: 1000px;
  height: 100px;
  background-color: red;
  vertical-align: middle;
}

実行イメージ

実行イメージ

単独でdisplay:table-cellを使ってよいのかはよく分かりません。

通常考えられるパターンとしてはこんな感じでしょうか。

<div class="box2">
  <div class="box3">
    説明
  </div>
  ここに説明が入ります。ここに説明が入ります。ここに説明が入ります。
  ここに説明が入ります。ここに説明が入ります。ここに説明が入ります。
  ここに説明が入ります。ここに説明が入ります。ここに説明が入ります。
  ここに説明が入ります。ここに説明が入ります。ここに説明が入ります。
  ここに説明が入ります。ここに説明が入ります。ここに説明が入ります。
  ここに説明が入ります。ここに説明が入ります。ここに説明が入ります。
</div>
.box2 {
  display: table;
  width: 100%;
  height: 100px;
  border: 1px solid black;
}

.box3 {
  display: table-cell;
  width: 10%;
  background-color: red;
  vertical-align: middle;
}

実行イメージ

実行イメージ

3.position:absolute + margin:auto 0;

次はおそらく子要素が何であっても使える設定です。

これは「top、bottom、heightがauto以外」かつ、「margin-topとmargin-bottomがauto以外」の場合にmargin-topとmargin-bottomの値が等しくなるというCSSの仕様に基づいた設定となります。

この仕組みについてはこちらの記事が参考になります。

<div class="box1">outer
  <div class="box2">inner
  </div>
</div>
.box1 {
  position: relative;
  height: 100px;
  background-color: red;
}

.box2 {
  position: absolute;
  background-color: yellow;
  height: 20px;
  top: 0;
  bottom: 0;
  margin: auto;
}
実行イメージ

「left、right、widthがauto以外」かつ、「margin-leftとmargin-rightがauto以外」の場合にmargin-leftとmargin-rightの値が等しくなる、というCSSの仕様に基づき、 左右方向についても同じように中央揃えできます。この場合はCSSの.boxにwidth:20px、left:0、right:0などと追加すればOKです。

これ、便利なことは便利なのですが、heightやwidthを設定しなければならず、高さや幅を成り行きとしたい場合には使えません。

そこで次の方法。

4.top:50% + transform:translateY(-50%)

子要素を親要素の中でずらす設定となります。こちらも子要素が何であってもたいてい使える方法になっています。

ポイントは、

  • 親要素にposition:relativeを設定
  • 子要素にposition:absoluteを設定
  • 子要素にtop:50%、およびtransform:translateY(-50%)を設定

となります。

<div class="box1">outer
  <div class="box2">inner
  </div>
</div>
.box1 {
  position: relative;
  height: 100px;
  background-color: red;
}

.box2 {
  position: absolute;
  background-color: yellow;
  top: 50%;
  transform:translateY(-50%);
}

実行イメージ

仕組みとしてはこんな感じ。

この方法も左右方向に使えます。その場合は、box2にleft:50%transform:translateX(-50%)とします。上下左右とも中央にする場合は、transform:translateX(-50%) translateY(-50%)です。translateXとtranslateYは別の行に分けて設定すると後の方だけが効いてきますので、同じ行に空白で分けて設定する必要があります。

5.display:flex

次は親要素にdisplay:flexalign-items:centerを設定する方法。

<div class="box1">outer
  <div class="box2">inner
  </div>
</div>
.box1 {
  display: flex;
  align-items: center;
  height: 100px;
  background-color: red;
}

.box2 {
  background-color: yellow;
}

実行イメージ

こちらも左右方向にも設定できます。その場合、親要素にjustify-content:centerを追加すればOKです。

まとめ

以上、左右3つ、上下4つの中央揃えを紹介しました。

個人的にはtransformの方法が一番分かりやすくてしっくりきています。

他にも方法があれば追加していきたいと思います!