【CSS】中央寄せ「margin: 0 auto」が効かない!?その理由と詳しい解説

今回は、CSSで中央寄せをする際に使用する「margin: 0 auto」が効かない時の理由を解説します。

Webサイトを実装する際に必ず使うと思いますが、効かないと焦りますよね。

中央寄せと言ったらとりあえず「margin: 0 auto」と思っている方に、適切な使い方とその他の中央よせの方法を図を交えてわかりやすくお伝えします。

「margin: 0 auto」で中央寄せする方法

「margin: 0 auto」で中央寄せする方法について、実際のコードやデモを用いて説明していきます。

「margin: 0 auto」の正体

まずは、「margin: 0 auto」の正体を暴いていきます。

これはショートハンドという書き方で、省略されて記述されています。

省略しない場合は下記の4つに分かれます。

  • margin-top: 0;
  • margin-right: auto;
  • margin-bottom: 0;
  • margin-left: auto;

上記4つの中で中央寄せに関係のあるものは、

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

この2つです。

もし、中央寄せする要素に上下の余白がなければ、今まで通り「margin: 0 auto」を使用しても良いのですが、上下の余白がある場合は「margin: 0 auto」のままだと使用できません。

その場合は、上記のように個別に記述するか、ショートハンドなら上・左右・下の順で記述するので「margin: ○px(上の余白) auto ○px(下の余白)」と記述しましょう。

実際に「margin: 0 auto」で中央寄せしてみる

実際に実装したデモがこちらです。

コードはこちらです。

<body>
  <div class="wrapper">
    <div class="box"></div>
  </div>
</body>

CSSはこちらです。

body {
  margin: 60px 0;
}

.box {
  width: 300px;
  height: 300px;
  margin: 0 auto;
  background-color: plum;
}

どの画面幅にしても中央寄せになっていることがわかります。

中央寄せしたい.boxの大きさを指定し、その左右の余白を自動(auto)と指定することでどの画面幅でも.boxは中央にくるようになっています。

上下の余白が必要であれば、

.box {
  width: 300px;
  height: 300px;
  margin-top: 30px;
  margin-right: auto;
  margin-bottom: 30px;
  margin-left: auto;
  background-color: plum;
}

このように書きかえれば思い通りに実装することができます。

「margin: 0 auto」で中央寄せできない理由

「margin: 0 auto」を指定しても中央寄せにならない場合、どのような理由が考えられるでしょうか?

3つの考えられる理由を順番にみていきましょう。

display: inline / display: inline-block

「margin: 0 auto」はブロック要素に対して効くもので、インライン要素には効きません。

HTML5以降、ブロック要素やインライン要素という分類は廃止されましたが、この記事では便宜的にデフォルトのdisplayがblockになっている要素をブロック要素、デフォルトのdisplayがinlineとなっている要素はインライン要素と呼びます。

インライン要素は、テキストやimgタグ、aタグ等が挙げられます。

インライン要素にはインライン要素の中央寄せの方法があるので、その方法を記述しましょう。(後ほど紹介します)

ブロックとして中央寄せしたい場合は、

display: block;

上記を指定したい要素またはクラスに記述しましょう。

widthの指定なし

ブロック要素だとしても、横幅の指定がない場合は「margin: 0 auto」が効きません。

ブロック要素のwidthは初期値が親の100%なので、widthの指定がない場合は全面的に要素が広がっている状態になります。

この状態だと中央寄せできないですね。

この場合は、横幅を指定すれば中央寄せすることができます。

例えば、

width: 300px;

このように記述します。

float

floatプロパティは他のプロパティと少し違って、windowや親要素、その他の浮動要素によって位置が決まります。

イメージとしては、「浮いている」という感じです。

この場合、自動(auto)が効きません。

floatプロパティは要素の回り込みを指定するプロパティなので、中央寄せする方法がありません。中央寄せしたい場合はfloatプロパティを使用しない他の実装方法を考えましょう。

position: absolute

position: absolute;を使用している場合も、margin: 0 auto;で中央配置できません。

position: absolute;を指定しているようを中央寄せする方法は別であるので、その方法を使用しましょう。(後述します)

その他で中央寄せする方法

「margin: 0 auto」以外で中央寄せする方法を紹介します。

インライン要素を中央寄せする

インライン要素の中央寄せは「text-align: center」を使用します。

実際に文字の場合と画像の場合を見ていきましょう。

文字の場合

文字を中央寄せする場合は文字を囲んでいるタグに「text-align: center」を指定します。

実際のコードをご覧ください。

<div class="wrapper">
  <p>これはデフォルトです</p>
  <p class="center">これは中央寄せです</p>
</div>

下はCSSです。

body {
  background-color: #eee; //見やすいように色をつけました
}

.center {
  text-align: center;
  background-color: #fff; //見やすいように色をつけました
}

上記のコードをブラウザで表示すると下のようになります。(わかりやすいように背景とpタグに色をつけました)

pタグ(白い部分)はブロック要素なので親要素の100%の横幅で広がっています。

その中のテキストはデフォルトでは左によっていますが、「text-align: center」を指定したテキストは中央寄せになっていることがわかります。

画像の場合

画像のimgタグもインライン要素なので「text-align: center」を指定すれば中央寄せすることができます。

<div class="wrapper">
  <figure><img src="./images/photo.jpg" alt="鮮やかなピンクのチューリップがたくさん" width="300"></figure>
  <figure class="center"><img src="./images/photo.jpg" alt="鮮やかなピンクのチューリップがたくさん" width="300"></figure>
</div>

CSSはテキストで使用した.centerを使用しました。

実際のブラウザ表示は下のようになります。

「text-align: center」を指定するのはimgタグではなく、そのラッパー要素に指定しましょう。

画像もテキストと同様に中央寄せにできました。

position:absoluteで中央寄せする

「margin: 0 auto」では中央寄せできない、position:absoluteの中央寄せの方法をご紹介します。

実際のコード

実際に実装した時のコードはこちらです。

<div class="wrapper">
  .wrapper
  <div class="box">.box</div>
</div>

下はCSSです。

.wrapper {
  position: relative;
  width: 300px;
  height: 300px;
  background-color: #eee; //見やすいように色をつけました
}

.box {
  width: 100px;
  height: 100px;
  background-color: #fff;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

ブラウザではこのように表示されます。

positionプロパティで中央寄せするポイント

positionプロパティで中央寄せする際のポイントは2点あります。順番にみていきましょう。

親要素にposition: relativeを必ずつける

position: absoluteは、position: relativeを指定した親要素を基準とした位置に配置されます(厳密には、position: fixedなどstatic以外を指定した親要素)。

親要素にposition: relativeがないと、ページ全体が基準となるので思いもしないところに配置してしまいます。

transformで調整する

親要素に relative を使用し、中央寄せしたい.boxに absolute を指定したらあとに「top: 50%」「left: 50%」を指定して配置していきます。

その際、その状態だと.boxの上辺と左辺が.wrapperの上から50%、左から50%の位置に来てしまい中央にはなりません。

その時に使用するのが「transform」です。

「transform」は指定した数値の分、要素を移動するプロパティで、今回はx軸方向に.boxの横幅半分、y軸方向に縦幅半分をマイナスするように指定しています。

これによって中央寄せすることができました。

display: flexで中央配置する

「display: flex」を使用して中央配置する方法もあります。

実際のコード

  <div class="wrapper">
    <div class="box"></div>
  </div>

下はCSSです。

.wrapper {
  width: 330px;
  height: 270px;
  background-color: #eee; //見やすいように色をつけました
  display: flex;
  justify-content: center;
}

.box {
  width: 110px;
  height: 90px;
  background-color: #f8b6b6; //見やすいように色をつけました
}

ブラウザで表示を確認すると、このようになります。

「display: flex」を指定して、「justify-content: center」を指定すると中央寄せにすることができます。

「justify-content」は「display: flex」を使用する際に、水平方向に揃えるときのプロパティで初期値は「flex-start」で左側によります。

その他、「flex-end」「center」「space-between」「space-around」とありますが、今回は中央配置の「center」を使用します。

また、.wrapperに「align-items: center;」を追記すると天地中央になります。

「display: flex」はとても便利で、中央寄せ・天地中央にするのにCSSを3行追加するだけですみました。

横並びにする時だけでなく、中央寄せも簡単にできます。

まとめ

今回は、CSSで中央寄せをする際に使用する「margin: 0 auto」が効かない時の理由を解説しました。

中央寄せと言ったらとりあえず「margin: 0 auto」という段階から一歩ステップアップしたのではないでしょうか?

ブロック要素とインライン要素でも中央寄せの方法が違いますし、場合によっては「display: flex」やpositionプロパティを使用した方がいい場合もあります。

まずは、この記事を参考にして「margin: 0 auto」を深く理解し、使える場面を分けていきましょう。


その他の記事