CSS GridとFlexboxの使い分け 第1回 テキスト量が変化する要素を並べる

いくつかの実務でよく扱う特徴的なレイアウトをCSS GridとFlexboxの両方で作り、使い分けるための勘所を身に付けましょう。1回目はテキスト量が変化する要素を並べるレイアウトを取り上げます。

発行

著者 坂巻 翔大郎 フロントエンド・エンジニア
CSS GridとFlexboxの使い分け シリーズの記事一覧

はじめに

2020年現在、CSS Gridはすでに多くのブラウザで利用できるようになっています。そうなったことで、CSS GridやFlexboxをどう使い分けたらよいのかと悩んでいる方を見かけることがあります。筆者は、過去に何度かCSS GridやFlexboxに関する記事を書いています。そして実務でもCSS GridとFlexboxを使う機会が多くあります。

本記事では、これまでの筆者の経験をもとに、どのようにCSS GridとFlexboxを使い分けているのかを解説します。

なお、記事がフォーカスするのは両者の異なる点であるため、CSS Grid、Flexboxの仕様や実装そのものは深く解説はしません。よろしければ、CodeGridの次のシリーズを参照してください。

筆者はどう使い分けているのか

この記事を書く際に、あらためて、普段、筆者はどのようにしてCSS GridとFlexboxを使い分けているのかを考えてみました。

そもそも、筆者は何かしらのレイアウトを実装する際、まずはじめにCSS Gridで実装できるかどうかを考えています。CSS Gridが適切でなければFlexboxで実装することを考え、Flexboxでも適切でなければ、それ以外の方法で実装を考えます。

実装しようとしているレイアウトが、CSS Gridに適しているかどうかの判断材料は筆者の中にいくつかあります。

  • テキストや要素が増えたときに、どういった見た目になるのか
  • 複数行ある場合に、行ごとにある要素の縦の位置を揃えたいか
  • レスポンシブデザインで、画面幅などが狭まった際にどのように変化するのか
  • あらかじめ枠の大きさを固定してその中に要素を収めるのか、それとも枠をよしなに調整するのか

筆者はこれらの判断材料をもとに、CSS Gridを使うか、Flexboxを使うかを考えています。

より具体的に伝わるように、このシリーズでは3つのレイアウト例を挙げ、それぞれをCSS GridとFlexboxの両方で実装します。CSS Gridで実装した場合と、Flexboxで実装した場合に、どういった違いがあるのか解説します。

レイアウト例は実務でも実際に手がけたパターンで、みなさんの業務でも出くわしそうなものを選びました。2つの実装方法を見比べることで、次のことが達成できるようにしましょう。

  • より的確に、CSS Gridを使うか、Flexboxを使うかを判断する
  • デザインだけではわからないが、実装判断に必要な情報を「こういう場合はどうするのか?」と自分で取りにいく

レイアウト例:テキスト量が変化する要素を並べる

まずは次の画像のように、要素を均等に並べる実装を考えてみます。

このデザインをCSS GridとFlexboxそれぞれで実装してみます。

CSS Gridで作ったもの

まずは、CSS Gridで実装されたデモを見てみましょう。

HTMLとCSSは次のようになっています。

元となるHTML

<ul>
  <li>text 1</li>
  <li>text 2</li>
  <li>text 3</li>
  <li>text 4</li>
  <li>text 5</li>
  <li>text 6</li>
</ul>

Girdでの実装

/* レイアウト */
ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, auto));
  gap: 30px;
}
/* 装飾 */
ul {
  max-width: 670px;
  list-style: none;
  padding: 0;
}
li {
  background-color: rgba(234, 88, 88, 0.2);
  font-size: 48px;
}

CSS Gridでは横方向に自動で繰り返すように列を作っています。必要に応じて折り返します。要素間の余白はgapプロパティで指定しています。

レイアウト例のデザインと同じ見た目を再現できています。ただレイアウト例には、テキストや要素が増減したときにどういう状態になるか明記されていません。

このデモのテキストや要素を変化させたときの見た目を見てみましょう。

テキストや要素の数が変化しても、各行の高さや各要素の頭の位置が揃っています。これがCSS Gridの特徴です。

Flexboxで作ったもの

次に、Flexboxで実装したものを見てみましょう。

HTMLとCSSは次のとおりです。HTMLはCSS Gridの元となったHTMLとまったく同じ構造です。

元となるHTML

<ul>
  <li>text1</li>
  <li>text2</li>
  <li>text3</li>
  <li>text4</li>
  <li>text5</li>
  <li>text6</li>
</ul>

Flexboxでの実装

/* レイアウト */
ul {
  display: flex;
  flex-wrap: wrap;
  margin: -30px 0 0 -30px; /* gapプロパティが使える場合は gap:30px; */
}
li {
  min-width: 150px;
  margin-top: 30px; /* gapプロパティが使える場合は削除 */
  margin-left: 30px; /* gapプロパティが使える場合は削除 */
}
/* 装飾 */
ul {
  max-width: 670px;
  list-style: none;
  padding: 0;
}
li {
  background-color: rgba(234, 88, 88, 0.2);
  font-size: 48px;
}

liの余白にはmarginを使いました。仕様ではCSS Gridと同じく、gapが使えるようになったのですが、執筆現在はFirefoxでしか実装を確認できません*。gapプロパティが使えないブラウザを対象にする場合は、要素間の余白をmarginプロパティを使って調整します。

*注:gapプロパティの実装

Chromiumでも実装の検討は始まっています。

デモを見ると、CSS Gridで実装したものと大差ありません。ですが、テキスト量や要素を増やしたときに違いが現れます。Flexboxで実装したデモのテキストや要素を増やしてみましょう。

テキストや要素の数が変化したときに、各行の高さは揃っていますが、各列の要素の頭の位置や幅は揃っていません。この場合、各li要素の幅を同じ数値にすれば頭の位置を揃えることはできます。

見比べてわかること

CSS Gridで実装されたものは、テキストや要素の量が変化したとしても、各行の要素の高さや、各列の頭の位置や幅を揃えることができていました。一方、Flexboxで実装されたものは、各行の高さは揃っていますが、各列の頭の位置や幅は揃っていません。

CSS Gridでの実装は商品の一覧など、たくさんの要素が並んだときに、テキスト量がバラバラでも、商品ごとの枠の高さや、頭の位置を揃えたいときに向いています。

一方、Flexboxは、たとえば、パンくずリストやタグクラウドのようなUIに適しています。

これらのUIは、複数行になった際に、各列の頭を揃える必要はありません。むしろ、行の中に一定間隔を保って、成り行きで配置されるのが常です。

デザインの要件によっては、CSS Gridで作ったもののように、行や列でちゃんと整列してほしいという場合もあります。

ですので、こういったデザインを実装する際は、必ず「要素が増加したらどうなるか?」「減少したらどうなるか?」「要素ごとのコンテンツ量はすべて一定なのか?」と思いを巡らさないといけません。その場合、デザインでは、どういった見た目が想定されているかを確認した上で、CSS Gridを使うのか、Flexboxを使うのかを決める必要があります。

まとめ

今回は要素を「並べる」ということに着目して、CSS GridとFlexboxの違いを解説しました。次回は画面幅によって変化するレスポンシブなデザインを例に比較してみましょう。