justify-contentに頼らない、Flexbox×margin: autoで手軽レイアウト
Webサイト作ってるとき、レイアウト調整といえば、大抵Flexboxを使っています。
でも実装しているときに気づくのが、親要素(Flexコンテナ)にてjustify-contentだけで配置しようとしすぎちゃう点。
/* 親側で左右の振り分けをしがち */
.parent {
display: flex;
justify-content: space-between;
}
それで済むことも多いんですけど、実案件とかでは「このボタンを右端に固定したい」「この要素だけ別の位置に置きたい」みたいなピンポイントな要望もあったりする。
そんなときに使えるのが、Flexboxとオートマージン(margin: auto)の組み合わせです。
justify-contentだと使えない場面
親要素にjustify-contentをつけると、コンテナ内のアイテムをまとめて調整できるので便利ですが、先ほど書いたように次のようなイレギュラーな配置に使えなかったりします。
- ナビゲーション: ロゴとメニューは左側に寄せて、ログインボタンだけ右側に寄せたい。
- カード: テキスト量がバラバラでも、続きを読むボタンはいつも最下部にくっつけたい。
こういうのをjustify-contentで対応しようとすると、それだけのために余計なdivを増やしたりして、コードが複雑になって可読性が悪くなったり…
Flexboxでのmargin: autoが意外と使える
でも、子要素(Flexアイテム)にmargin: autoを設定するだけであっさり解決できます。
通常のブロック要素(display: block)では、「margin: auto=左右の中央揃え」が一般的で、上下方向だと0と計算されて効かない仕様です。
でもFlexboxのコンテナ内だと違った動きをして、上下左右すべての方向でオートマージンが効くようになります。
Flexアイテムに、上下左右どれかのオートマージンをつけたら、その方向にある空きスペースをすべて吸収して、アイテム自身は反対方向に押し出されます。
たとえば横並びのヘッダーでmargin-left: autoにすると、左側のマージンが余白を全部取っていくので、結果的にアイテムが右に押されるような感じです。同じく、縦並びのカードでmargin-top: autoにすれば、ボタンを一番下に押し下げることができます。
オートマージンを活用したレイアウト
ナビゲーションで「ボタンだけ右寄せ」
ナビ内に、ロゴとメニューがあって、ログインボタンだけを右端に寄せたいとき。
HTML
<nav class="flex-container">
<div class="logo">LOGO</div>
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Service</a>
<a href="#" class="login-btn">Login</a>
</nav>
CSS
.flex-container {
display: flex;
align-items: center;
}
.login-btn {
/* 左側の余白をすべて吸収し、右端へ押し出される */
margin-left: auto;
}
カードレイアウトで「ボタンを下端に固定」
ブログカードなどの、説明文の長さがバラバラでも、ボタンの位置を一番下に揃えたいとき。
.card {
display: flex;
flex-direction: column; /* 縦方向に並べる */
height: 400px;
}
.card-button {
/* 上側の余白をすべて吸収し、一番下へ押し下げる */
margin-top: auto;
}
使うメリット
ラッパー要素が不要になる
「右側グループ」みたいなダミーのdivを作る必要がなくなります。記述がシンプルになるので、あとで保守のときに楽です。
読みやすい
「この要素を右に寄せたい」という意図が、コードを見た時にすぐ分かりやすいです。margin-left: auto というプロパティ名そのものが、やってることを説明してくれるような感じです。
レスポンシブに強い
position: absoluteみたいに無理やり固定するのと違って、Flexboxの計算ルールの中で動作するので、画面サイズが変わってもレイアウトが崩れにくいです。
正直なところ
でも全部オートマージンでやる必要はないです。
複数の要素を均等に並べたいなら、素直にjustify-contentを使うようにして、でもこの要素だけ例外的に動かしたいってときは、オートマージンの出番にする。そう使い分けてみるのが、楽なコーディングにつながるかもしれません。
