Figmaのデザインを見ながら模写コーディングをしていたとき、ボタンを中央に配置しようとして少しつまずきました。
ボタンの中の文字を中央に配置するため、最初に書いていたCSSがこちらです。
.help-button {
width: 192px;
height: 62px;
display: inline-flex;
justify-content: center;
align-items: center;
margin: 0 auto;
}
justify-content: centerとalign-items: centerで文字はボタンの中央に配置できています。
さらにmargin: 0 autoを指定したので、ボタン自体も中央に来ると思っていました。
ところが、ボタンは中央に来ませんでした。
そこで、
display: inline-flex;
を、
display: flex;
に変更すると、今度はmargin: 0 autoで中央に配置できました。
なぜでしょうか。
調べてみると、flexとinline-flexの違いだけでなく、「ボタンの中身を中央にすること」と「ボタン自体を中央にすること」は別の話だということが分かりました。
display: flexとinline-flexの違い

flexとinline-flexは名前が似ています。
実際、どちらを指定しても要素はFlexコンテナになり、その子要素をFlexboxで配置できるようになります。
違うのは、主にFlexコンテナ自身が周囲のレイアウトでどう扱われるかです。
display: flexはブロックレベルとして扱われる
.box {
display: flex;
}
display: flexを指定すると、その要素は外側に対してブロックレベルのFlexコンテナとして振る舞います。
イメージとしては、
外側:ブロック
内側:Flexbox
です。
そのため、幅を指定したブロックを左右のmargin: autoで中央に配置する、というよく使われる方法が使えます。
.help-button {
width: 192px;
display: flex;
margin: 0 auto;
}
今回ボタンを中央に配置できたのも、この形です。
display: inline-flexはインラインレベルとして扱われる
一方で、
.box {
display: inline-flex;
}
とすると、内側では同じようにFlexboxを使えますが、要素自身は外側に対してインラインレベルとして振る舞います。
つまり、
外側:インライン
内側:Flexbox
です。
inline-flexだからFlexboxが使えないわけではありません。
justify-contentやalign-itemsはどちらでも使えます。
違うのは、そのFlexコンテナ自身を周囲にどう配置するかです。
なぜmargin: 0 autoで中央揃えできなかった?

今回混乱した原因は、margin: 0 autoとjustify-content: centerが、どちらも「中央」に関係するCSSだったことです。
しかし、この2つは中央にする対象が違います。
margin: 0 autoは要素自体の配置に使う
幅を指定したブロックレベルの要素なら、
.help-button {
width: 192px;
margin: 0 auto;
}
とすることで、左右の余ったスペースがautoのmarginに割り振られ、要素自体を中央に配置できます。
今回inline-flexからflexへ変更したことで、ボタンはブロックレベルのFlexコンテナとして扱われるようになりました。
その結果、指定していたmargin: 0 autoによる中央配置が意図した形で機能した、というわけです。
justify-contentはボタン自体を中央にするCSSではない
もう一つ勘違いしていたのが、
justify-content: center;
align-items: center;
の役割です。
これらは、Flexコンテナの中にある子要素を配置するためのCSSです。
たとえば、
<a class="help-button" href="#">Help Me</a>
なら、justify-content: centerやalign-items: centerで調整しているのは、ボタンそのものではなく中にあるテキストの位置です。
つまり今回必要だったのは、
ボタンの中の文字を中央にする
→ justify-content・align-items
ボタンそのものを中央にする
→ 親要素との関係で配置を決める
という2つの別々の中央揃えでした。
ここを分けて考えると、かなり理解しやすくなりました。
inline-flexを中央揃えしたい場合は?

では、inline-flexでは中央揃えできないのでしょうか。
もちろん、そんなことはありません。
中央にする方法が違うだけです。
親要素にtext-align: centerを指定する
inline-flexの要素を中央に配置する方法の一つが、親要素へのtext-align: centerです。
<div class="button-area">
<a class="help-button" href="#">Help Me</a>
</div>
.button-area {
text-align: center;
}
.help-button {
display: inline-flex;
width: 192px;
height: 62px;
justify-content: center;
align-items: center;
}
inline-flexは外側に対してインラインレベルとして扱われるため、親要素のtext-align: centerによって中央へ配置できます。
つまり、
「inline-flexでは中央揃えできない」わけではありません。
今回たまたまdisplay: flex+margin: 0 autoという組み合わせが、作りたいレイアウトに合っていたということです。
flexとinline-flexは目的で使い分ける
flexとinline-flexのどちらが優れているというものでもありません。
たとえば、独立したボックスとして配置しながら、その中身をFlexboxで整えたいならflexが使いやすいでしょう。
一方、テキストやほかのインライン要素との流れを保ちながら、中身にはFlexboxを使いたい場合はinline-flexが便利です。
判断するときは、**「中身をどう並べるか」だけでなく、「その要素自体を周囲の中でどう扱いたいか」**まで考えるのがポイントです。
【まとめ】flexとinline-flexは外側の振る舞いが違う

display: flexとdisplay: inline-flexは、どちらも子要素をFlexboxで配置するために使えます。
大きな違いは、Flexコンテナ自身が外側に対してどう振る舞うかです。
display: flex:外側はブロックレベル、内側はFlexboxdisplay: inline-flex:外側はインラインレベル、内側はFlexboxjustify-content:Flexコンテナ内の子要素を配置するmargin: 0 auto:今回のような幅を指定したブロックを中央配置するときに使えるinline-flexを中央にしたい場合は、親要素のtext-align: centerなどを使える
今回、inline-flexからflexへ変更したことでボタンが中央に来たのは、Flexboxそのものが直ったからではありません。
ボタンの中身をどう配置するかと、ボタン自身をどう配置するか。この2つを同じ「中央揃え」として考えていたことが、つまずいた原因でした。
CSSで思った位置に要素が動かないときは、プロパティだけを見るのではなく、**「今、どの要素の位置を変えようとしているのか」**を確認すると原因を見つけやすくなります。