PPP's Blog

雑コード帳

flexboxを使って可変型のカラムでも同じデザインが崩れないようにする

TL,DR

  • 実現したいこと:2カラムのリストを縦に並べるときに、最後の列だけ1カラムになったりすることがあるが、そのときでも間延びせずにレイアウトしたい
  • justify-contentspace-aroundspace-evenlyでは最後の列が1カラムになると、その要素が真ん中に配置されてしまう
  • 1:リスト要素に対してwidthを指定することで実現できる
  • 2:最後のやつだけmarginを効かせるようにセレクターを設定することでも実現可能

やりたいこと

f:id:code-zen:20191012140106p:plain

こんな感じに2カラム横並びのリストを作成します。

最後の列が1カラムになったとき、それが左側に、上と同じように配置されて欲しいのです。

マークアップはこんな感じです。

<ul>
  <li>test_1</li>
  <li>test_2</li>
  <li>test_3</li>
</ul>

やったこと(失敗)

2カラムレイアウトならflexで、間に空白も入れたいからjustify-contentspace-evenlyにでもするかな...。 と思って、最初にこんなCSSを書きました。

ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
}

li {
  width: 48%;
}

f:id:code-zen:20191012150024p:plain

結果がこのスクリーンショットですが、1カラムになってる最後の列だけ、 要素が真ん中に配置されてしまいました。

次にやったこと(成功)

CSSセレクタで、次の条件を指定できないかな...と思いました。

  • 最後のli要素が奇数個目

できました

CSSに次の記述を足すと指定できました。

li:nth-last-child(1):nth-child(odd)

さっきの条件指定、分解してみるとこんな感じになるかと思います。

  • li要素の最後
  • li要素の中で奇数番目

これらをつなぐことで目的の条件を指定することが可能になりました。

ということで、最後のli要素かつ、それが奇数であったときにだけmargin-right:autoを指定することができました。

li:nth-last-child(1):nth-child(odd) {
  margin-right: auto;
}

こんな感じになります。

See the Pen yLLeJjP by itsumoonazicode (@itsumoonazicode) on CodePen.

もう一つやってみたこと(成功)

単純にli要素にwidthを設定しました。

今回は2カラムなので、だいたい46%ぐらいの数値を設定するとうまい具合に調整できました。

See the Pen flexbox 2 column layout by itsumoonazicode (@itsumoonazicode) on CodePen.

おまけ

これは上のものと同じような感じなんですけど、flexというショートハンドを使います。

See the Pen flexbox-based grid systems by itsumoonazicode (@itsumoonazicode) on CodePen.

このページを見つけて、最初はこの方法で実装をしたのですが、 結局今回に関してはwidth指定でも良いなということで見送りました。 (よく理解できなかった点があるので...)

Mastering Wrapping of Flex Items - CSS: Cascading Style Sheets | MDN

こちらの記事は、gridレイアウトをflexでもやるにはということも書かれています。

その際に出てきたのが、flexというプロパティなんですけど、これは

  • flex-grow
  • flex-shrink
  • flex-basis

の3つをまとめて指定するためのショートハンドだそうです。 いろんな記事を見る限り、flex-basiswidthを指定するのとあまり変わらないみたいなのですが、

よくわかっていません。。。