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を使うようにして、でもこの要素だけ例外的に動かしたいってときは、オートマージンの出番にする。そう使い分けてみるのが、楽なコーディングにつながるかもしれません。