【CSS】margin: 0 auto;が効かない理由と効かないときの対策。

CSS

コーディングで要素を中央寄せにしたいとき、margin: 0 auto;をよく使用しています。
ですが、ごく稀に機能しないことがあり、中央寄せに苦労してしまうときがあります。

毎回調べているのも面倒なので、今回は、私が遭遇した事例と合わせて解決した方法を記録していこうと思います。

本記事に書いてること。

  • margin: 0 auto;が効かない理由
  • margin: 0 auto;が効かないときの対策
  • margin: 0 auto;が効かないときの代用

margin: 0 auto;が効かない理由

結論から言うと、marginのautoはblock要素にしか影響を与えません。

marginのauto以外は、inline-block要素もしくは、block要素に適用されるので、勘違いしがちなところです。

つまり、autoを適用させたい要素をblock要素にするか、適用させたい要素をブロック要素で包括してあげればいいわけです。

ただ、block要素自体は親要素の幅いっぱいまで広がる特性があるので、幅も指定してあげる必要があります。

適用される条件をまとめると、以下のとなります。

  • block要素にしか、autoが適用されない。
  • widthを指定してあげる必要がある。

上記の条件に当てはまらない場合は、margin: 0 auto;は機能しません。

私が遭遇した事例。

効かない理由は、わかりました。
ここからは、私が遭遇した実務で発生した内容をもとに、効かないときの対策を考えていこうと思います。

まず、私が遭遇した事例から。

//HTML
        <h2 class="title">
          <span class="title-name">ここにタイトルが入ります。</span>
        </h2>

//css
.title:before {
    content: '';
    display: block;
    width: 69px;
    height: 30px;
    margin: 0 0 10px;
    background: url(../img/common/icon.png) no-repeat center center;
    background-size: 100% auto;
}

.title .title-name {
    display: block;
    font-size: 28px;
    font-size: 2.8rem;
    font-weight: 400;
    letter-spacing: .1em;
    line-height: 1.5;
}

h2を親要素として、中にspanが入っている要素です。
さらに、h2に擬似要素を適用させることで、画像(アイコン)を表示させています。

この要素をページ上に表示させると、幅いっぱいにh2が広がり、テキストとアイコンが左側に表示されるかたちになります。

上記の要素を中央寄せにしていきます。

h2の要素に幅を指定して、margin: 0 auto;を適用する。

前述した条件を考えれば、この方法が一番簡単で早い方法です。

ですが、実務ではなかなかそうも行きません。

まず、タイトルテキストがどの程度の長さになるのか、わからない以上幅を指定するわけにもいきません。

タイトルテキストが明確になったあとに、widthを指定してもいいのですが、タイトルごと個別にwidthを指定するのは、あまり好ましくありません。(というか、面倒です・・・)

なので、widthを指定してmargin: 0 auto;という単純な解決方法では、だめそうです。

ここが、実務の難しいところです。
常に汎用性の高い記述を考えていかなくてはなりません。

HTML要素を追加してtext-align: center;を適用させる。

私は、以下のようにして今回の事例を対処しました。

//HTML
        <div class="title_wrap">
          <h2 class="title">
            <span class="title-name">ここにタイトルが入ります。</span>
          </h2>
        </div>

//css
.title_wrap {
   text-align: center;
}
.title_wrap .title {
  display: inline-block;
}
.title:before {
    content: '';
    display: block;
    width: 69px;
    height: 30px;
    margin: 0 0 10px;
    background: url(../img/common/icon.png) no-repeat center center;
    background-size: 100% auto;
}

.title .title-name {
    display: block;
    font-size: 28px;
    font-size: 2.8rem;
    font-weight: 400;
    letter-spacing: .1em;
    line-height: 1.5;
}

対処した内容は、至ってシンプルです。

まず、「.title」タグを「.title_wrap」で囲ってあげます。
「.title_wrap」には、text-align: center;を適用させます。

text-align: center;は、inline要素もしくは、inline-block要素を中央寄せにします。注意点としては、中央寄せにしたい要素の親要素に適用させなければならないということです。そのため、今回は「.title_wrap」を新たに記述しました。

そのあと、「.title」をdisplay: inline-block;にします。

inline要素ではなく、inline-block要素なのは、inline要素になると、marginだけでなく、paddingまで適用されなくなってしまうためです。また、inline要素になると、HTMLの記述の影響を受け、予期せぬ余白や、改行がうまれます。そのため、「inline-block要素」としました。

これで、「.title_wrap」(親要素)に適当させたtext-align: center;が適用されて、「.title」(子要素)が中央寄せになります。

上記の対応方法であれば、テキストへ幅を個別に指定する必要もなく、テキストの長さが変わっても問題ありません。汎用性の高い記述で、中央寄せにすることができました。

margin: 0 auto;以外で要素を中央寄せにする方法。

中央寄せにできない原因がわかったら、margin: 0 auto;に固執せず、別の方法をとるのも1つの方法です。
widthとblock要素の指定をしても、汎用性が高く、後々の更新や変更などにも柔軟に対応ができるのならいいのですが、widthを指定する時点でそうはなりません。

なので、原因を理解して、widthとblock要素の指定では汎用性に欠けると判断した場合は、別の方法を検討していきましょう。

最後は、margin: 0 auto;以外で中央寄せにならない原因を書いて、終わりにしたいと思います。

floatプロパティが適用されている。

margin: 0 auto;を適用させる要素にfloatプロパティが適用されている場合も、margin: 0 auto;は効きません。floatは、要素が浮いているような状態になってしまうためです。floatを解除するか、私が実践で対応したように、HTML要素に手を加える方法で対策しましょう。

position: absolute;が適用されている。

float同様にpositionプロパティのabsoluteが適用されているときも、margin: 0 auto;は効きません。
absoluteの状態は、相対位置で要素の位置が決定しているのためです。解除するか、positionプロパティを使った中央寄せの方法を実践してみてください。

頻出する記述は、リセットCSSへ記述しておく。

今回のように、「要素を中央寄せにしたい!」などの頻出する記述については、度々原因を調べているのでは時間がかかってしまい、手間です。

そうならないためにも、事前にリセットCSSなどのベースとなるスタイルシートに指定しておきましょう。

spanタグやaタグは、デフォルトではinline要素です。

でも、中央寄せにしたりする機会は意外多いと思います。

リセットCSSに予め、block、もしくはinline-blockと指定しておけば、都度指定する手間が省けるだけでなく、意識せずに指定してもスタイルが適用されるので、エラーを探す必要がなくなります。

決まったリセットCSSをお持ちでない方は、下記の記事を参考に、自分独自のリセットCSSを作ってみてください。

関連記事

私が勤務する会社でコーディングのルールを決めることになりました。 ルールの中でリセットCSSはなにを使用するか。という議題になったので、私が調べた内容と、結論を記録しておこうと思います。 最後には、私が使っているノーマライズC[…]