CSSでボタンやボックスを中央に配置しようとして、margin: 0 autoを指定したのに動かなかったことはありませんか?
幅を指定しているのに左側に寄ったままだったり、別の要素では同じCSSが効いたりすると、原因がわかりにくいものです。
実際にWebサイトを模写していたときも、ボタンを中央に配置しようとしてmargin: 0 autoを指定したものの、思ったように動かないことがありました。
原因を確認すると、要素のdisplayプロパティが関係していました。
この記事では、margin: 0 autoが効く条件と、中央揃えできないときの対処法を、具体的なコードとともに解説します。
margin: 0 autoで中央揃えできる仕組み

margin: 0 autoは、CSSで要素を水平方向の中央に配置するときによく使われる指定です。
ただし、すべての要素に指定すれば中央に移動するわけではありません。まずは基本的な仕組みを確認しましょう。
margin: 0 autoの意味とは?
marginは、要素の外側の余白を指定するプロパティです。
.box {
margin: 0 auto;
}
この書き方では、上下の余白を0、左右の余白をautoに設定しています。
通常の文書フローにあるブロックレベルの要素では、幅が親要素より小さく、左右に余白が残っている場合、その余白を左右に均等に配分できます。
例えば、次のようなHTMLとCSSです。
<div class="box">BOX</div>
.box {
width: 300px;
margin: 0 auto;
background-color: #e15252;
}
親要素に300pxより広い表示領域があれば、.boxを水平方向の中央に配置できます。
つまり、margin: 0 autoは要素そのものの左右の余白を調整する方法です。
中央揃えには幅と表示形式が関係する
margin: 0 autoで中央揃えするには、要素の幅と表示形式が重要です。
例えば、通常のブロック要素はwidth: autoの状態で親要素の利用可能な幅いっぱいに広がることがあります。
この場合、左右に分配する余白が残らないため、margin: 0 autoを指定しても見た目は変わりません。
.box {
width: 60%;
margin: 0 auto;
}
このように幅を親要素より小さくすると、左右に余白が生まれ、中央に配置できるようになります。
ただし、幅を指定するだけでは解決しない場合もあります。
その代表例が、displayプロパティによる違いです。
margin: 0 autoが効かない主な原因

margin: 0 autoを指定しても中央揃えできないときは、まず要素のdisplayを確認しましょう。
特に、inlineやinline-flexを使っている場合は注意が必要です。
display: inlineやinline-flexでは中央揃えできない
次のようなボタンを考えてみましょう。
<div class="wrapper">
<a class="button" href="#">Help Me</a>
</div>
.button {
display: inline-flex;
width: 160px;
height: 46px;
margin: 0 auto;
justify-content: center;
align-items: center;
background-color: #e15252;
}
inline-flexは、要素の内部をFlexboxとして扱いながら、要素自体はインラインレベルとして配置する指定です。
そのため、通常のブロック要素のように左右のautoマージンで中央に配置することはできません。
ボタンの中身が中央に揃っていても、ボタンそのものが中央に移動するとは限らないのです。
ここで重要なのは、justify-contentやalign-itemsが調整しているのは、ボタン内部の子要素の配置だという点です。
display: blockやflexに変更する
ボタンをブロックレベルの要素として扱いたい場合は、displayを変更する方法があります。
.button {
display: flex;
width: 160px;
height: 46px;
margin: 0 auto;
justify-content: center;
align-items: center;
}
display: flexを指定した要素は、通常の文書フローではブロックレベルのFlexコンテナになります。
そのため、幅を指定して左右の余白が残っていれば、margin: 0 autoで中央に配置できます。
ボタン内部の文字もFlexboxで中央に揃えられるため、今回のようなケースでは使いやすい方法です。
ただし、inline-flexが間違っているわけではありません。
インラインレベルの要素として配置したい場合には、別の中央揃え方法を選ぶこともできます。
margin以外で要素を中央揃えする方法

中央揃えの方法はmargin: 0 autoだけではありません。
要素の表示形式や親要素のレイアウトに応じて、適切な方法を選びましょう。
親要素にtext-align: centerを指定する
inline-flexのボタンを中央に配置したい場合は、親要素にtext-align: centerを指定する方法があります。
.wrapper {
text-align: center;
}
.button {
display: inline-flex;
width: 160px;
height: 46px;
justify-content: center;
align-items: center;
}
inline-flexはインラインレベルの要素なので、親要素のtext-alignによる水平方向の整列対象になります。
この方法なら、ボタンのdisplayを変更せずに中央へ配置できます。
なお、text-align: centerを指定するのは、中央に置きたいボタン自身ではなく、ボタンを含む親要素です。
親要素をFlexboxにする
もうひとつの方法は、親要素をFlexコンテナにすることです。
.wrapper {
display: flex;
justify-content: center;
}
.button {
width: 160px;
height: 46px;
}
通常のflex-direction: rowでは、justify-content: centerによって子要素を横方向の中央に配置できます。
この場合、ボタン自体にmargin: 0 autoを指定する必要はありません。
複数のボタンを並べたり、要素同士の間隔を調整したりする場合にも便利です。
【まとめ】margin: 0 autoはdisplayと幅を確認する

margin: 0 autoが効かないときは、まず要素のdisplayと幅を確認しましょう。
通常の文書フローにあるブロックレベルの要素なら、親要素より小さい幅を指定し、左右に余白を残すことで中央に配置できます。
一方、inlineやinline-flexでは、同じ方法で中央揃えできない場合があります。
その場合は、display: flexに変更するか、親要素にtext-align: centerやFlexboxを指定する方法が考えられます。
中央揃えで大切なのは、要素の中身を揃えたいのか、要素そのものを中央に置きたいのかを区別すること。
CSSが効かないときは、余白の数値を調整する前に、要素の表示形式と親子関係を確認してみましょう。