HTML&CSS

CSS GridとFlexboxの違いと使い分け(シミュレーター付)

さすがに最近は無駄にCSSのfloatを使っているコーディングを見る機会も減りました。Flexboxを適切に使っているケースは増えてきていますが、CSS Gridはまだまだ普及していないように感じられます。どちらもやれることが似ていて、どういう風に使い分ければ良いかがいまいちピンと来てない方もいらっしゃるのではないでしょうか?

よく似た性質をもつこの2つ、それぞれどういう風に動くのかをシミュレーションできるようにしました。そのうえで、どういう風に使い分ければ良いのかをご紹介したいと思います。

Flexboxの方が記述がシンプルなので、Flexboxで問題ないケースはFlexboxを使うのが良いですが、CSS Gridを使わないと実現できないこともあります

過去にCSSで行われたレイアウト

まず先にここでご紹介する方法は、現在においては採用するべきではない方法となります。ご存じの方は飛ばしてください。

tableレイアウト

table要素は表組を作成するためのものですが、tableの線が表示されないようにしてレイアウトのために使用するという方法が取られた頃があります。

しかしこれ、当時から問題視されていました。といいますかNGです。表は表。アクセシビリティの観点でNGというわけです。何が問題かは、スクリーンリーダーでどう読み上げられるかを想像していただければわかるかと思います。『表、見出し〇〇、・・』という感じになります。そもそも、どのセルがどの見出しに対してのものなのか、がわかるように記述してないと、もはやハチャメチャ(なコーディングがほとんどなのが実態)なのですが、脱線するのでその話はここでは置いておきます。気になる方はアクセシビリティのカテゴリーの記事を見てください。

floatでのレイアウト

これは今でもよく見かけます。なので冒頭、Flexboxも使い慣れてない方いらっしゃいますか?と言いました。tableレイアウトほどの問題は抱えていないため、通常縦に並ぶ要素を横に並べたいときに、当時はfloatでレイアウトする、という選択肢が取られましたが、FlexboxとCSS Gridがある現在においては、floatを本来の用途以外のために使用するのはやはりアクセシビリティのために避けるべきと言えます。

floatは対象要素を左ないしは右に寄せ、他の要素を回り込ませる、という用途において用いるためのものです。

Flexbox

Flexboxの概要

Flexboxは、その直下の子要素同士に対して以下のような指定ができます(他にも指定可能なプロパティがあります)。

  • 横並び/縦並び
  • 縦方向の揃え方(上揃え/中央揃え/下端揃え/均等揃えなど)
  • 横方向の揃え方(左揃え/中央揃え/右揃え/均等揃えなど)

また、orderプロパティを用いることで、HTMLの記載順とは異なる順番で表示するということも可能です。

Flexboxのシミュレーター

プロパティ値の変更でどう変わるかを確認しやすいようにしてみたので、ぜひいじってみてください。

80%
10px
※表示崩れ防止のためスマートフォンなど幅の狭い端末ではwrapで固定されます。PCでご利用ください。

Flexboxシミュレーション

box-01

box-02

box-03

box-04

box-05

flexプロパティ

上のシミュレーターにも入れてないのですが、Flexboxには、flexプロパティというのがあります。
flexプロパティは、displayプロパティをflexにした要素の子要素に対して付けるプロパティで、各子要素の幅の比率を定めることができます。

HTML

<div class="flex-box">
   <div class="box-01">
   <div class="box-02">
</div>

CSS

.flex-box{
   display: flex;
}
.box-01{
   flex: 1;
}
.box-02{
   flex: 2;
}

このようにすると、box-01とbox-02の幅の比率は、1:2で横に並びます。

flex-basisプロパティ

flex-basisプロパティは、displayプロパティをflexにした要素の子要素に対して付けるプロパティで、各子要素の幅を定めることができます。

先ほど示したのと同じHTMLに対して、次のようにflex-basisプロパティを定めると、box-01の幅は100pxで固定されます。

.flex-box{
   display: flex;
}
.box-01{
   flex-basis: 100px;
}

CSS Grid

CSS Gridの概要

CSS Gridは、その直下の子要素を格子状にグリッドで分け、各マス(グリッドトラックと呼びます)の配置について以下のような指定ができます。

  • 横、縦にそれぞれいくつのグリッドトラックを並べるか
  • 各グリッドトラックの大きさ
  • 各グリッドトラック内の配置

Flexboxと同様に、orderプロパティを用いることでHTMLの記載順とは異なる順番で表示するということも可能です。

CSS Gridのシミュレーター

こちらもシミューレータ―ご用意したのでお試しください。

80%
10px





CSS Gridシミュレーション

box-01

box-02

box-03

box-04

box-05

CSS Gridの「grid-template-columns」

grid-template-columnsは、横方向にいくつのグリッドトラックを並べ、それぞれの幅をどうするかを指定できるCSS Gridのプロパティです。

指定の仕方としては、

grid-template-columns: 100px 100px;

のようにカンマ無しで並べます。
以下のそれぞれについて、上のシミュレーターでいじりながらどういうことか把握してみてください。

fr

frは比率でグリッドトラックの幅を指定することができるものです。
1frとだけ書けば、横に並ぶグリッドトラックは1つなので、100%の幅となり、
1fr 1frと書けば、横に並ぶグリッドトラックは2つとなり、それぞれ100%を等幅で分ける、つまり50%ずつとなります。
2fr 3frと書くと、横に並ぶグリッドトラックは2つで、100%の幅を2:3の比率で分けます。つまり40%と60%です。
200px 1frと書くと、横に並ぶグリッドトラックは2つで、1つ目幅は200px、2つ目は残りの100%となります。

repeat

repeatは、何度も同じ内容を書くのを省略するためのものです。
repeat(繰り返す回数, グリッドトラックの幅)のように書きます。
例えば、1fr 1frrepeat(2, 1fr)は同じです。
2つならよいのですが、repeat(5, 1fr)と書けば1fr 1fr 1fr 1fr 1frと同じになりますので、分かりやすくなります。

minmax

例えばminmax(100px, 1fr)と書くと、そのグリッドトラックは最小値100px、最大値1frとなります。

auto-fillとauto-fit

次の図は上のシミュレーターで、repeat(auto-fill, minmax(100px, 1fr))repeat(auto-fit, minmax(100px, 1fr))をそれぞれ選んだ時の状態です。Chromeの開発ツールで選択すると、このようにグリッド、グリッドトラックの状態が視覚的に把握できます。

auto-fillは親要素の幅にスペースが余る場合、そこにグリッドトラックが作られた状態で、各グリッドトラックが等幅になります。
auto-fitは、親要素の幅にスペースが余る場合、グリッドトラックの幅がその分広がり、各グリッドトラックが等幅になります。

いずれも、メディアクエリ―を使わずにレスポンシブデザインを実現するのに適していると言えます。
なお、grid-template-rowsプロパティもあり、grid-template-columnsが横方向の並び方を決めるプロパティであるのに対して、縦方向に同様に配置することができるプロパティです。

CSS Gridの「grid-column」と「grid-row」

シミュレーターには入れてないですが、display: gridを適用した要素直下の子要素それぞれについて、1つずつ配置を指定できるのがgrid-columnプロパティとgrid-rowプロパティです。

次の図はCSS Gridを用いて雑誌風レイアウトをした本サイトのページを、Chromeの開発ツールでgridの状態を示したキャプチャです。

これは横に5つ、縦に3つのグリッドトラックを作り、各要素をgrid-columnプロパティとgrid-rowプロパティを使って配置しています。

Chromeで示されている数字は、各グリッドトラックの開始点と終了点を示します。例えば右上の画像は、

grid-column: 4 / 6;
grid-row: 1 / 2;

と指定されています。

grid-columnプロパティの値「4/6」の4は、横方向の4を開始点とすることを、6は横方向の6を終了点とすることを指定しています。
grid-rowプロパティの値「1/2」の2は、縦方向の1を開始点とすることを、2は縦方向の2を終了点とすることを指定しています。

同様に、左下の「Are you tring ‘User First’ ?」と書かれた部分の要素は、以下の指定で配置しています。

grid-column: 1 / 4;
grid-row: 3 / 4;

FlexboxとCSS Gridの比較

FlexboxとCSS Gridの似ている点

FlexboxとCSS Gridは共に、本来縦に並ぶ要素を横に並べ、またプロパティの設定により幅に応じて回り込ませることができる、という点では似ています。

gapプロパティは共に、

gap: 10px 20px;

のように書くと1番目の10pxが縦方向の間隔、2番目の20pxが横方向の間隔となります。

また、Flexboxはflexプロパティで、CSS Gridはgrid-columngrid-rowで、要素の並び順を変えられる点も似ているところと言えます。

FlexboxとCSS Gridの違い

回り込み方

Flexboxは、

flex-wrap: wrap;

にすると幅に応じて回り込みます。ただ、これは私としては使いづらいです。まだ回り込まなくていいよ、という幅でも回り込んでしまい、幅に応じて要素の幅を変えるという風にはならないからです。

対してCSS Gridは、

grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

このプロパティ設定により、Flexboxよりも簡単に思ったようなレスポンシブデザインにすることができます。

配置

配置は、どちらかといえばFlexboxよりもCSS Gridの方がより細かい指定ができるといえますが、Flexboxでないとできないこともあります。

例えば次の図のような違いが生じます。Flexboxはあくまでも要素同士でレイアウトされていくのに対して、CSS Gridはグリッドが生成され、そのグリッド同士でレイアウトされるという違いです。

これで見て分かる通り、Flexboxは2行以上となるグリッド表示にしたときに、全体は中央寄せにしつつ、1行目と2行目の左端の要素について、左の端を揃えるということができません。それをしたい場合はCSS Gridを用いることによって可能です。そのため、後述しますがグリッド表示したい場合はCSS Gridを用いることが私は多いです。

Flexboxを使うと良い場面

以下のような用途では私はFlexboxを用います。このようなケースは多いので、CSS GridよりもFlexboxを使うケースの方が圧倒的に多いです。

  1. 1つの要素を親要素に対して上下中央揃えにしたい場合
  2. ブロック要素同士を横並びにしたい場合
  3. 要素同士に一定間隔を空けたい場合

CSS Gridを使うと良い場面

CSS Gridを使うべき場面もありますし、私は少なからず使っています。
以下のような用途では私はCSS Gridを用います。

  1. 画像などをグリッド表示する場合
  2. 各要素を細かくレイアウトする場合

1の「画像などをグリッド表示する場合」において、前述のように各要素のサイズが異なる場合はFlexboxを利用した方が良いですが、そうでない場合、CSS Gridの方が自由が効くというのがあります。メディアクエリ―を用いずに下に回り込ませることはどちらもできますが、特定の幅から2つだけ横に並べる、といったことがCSS Gridの場合できます。

grid-template-columns: 1fr 1fr;

の記述で2列を横に並べることになりますので、メディアクエリ―を使って、特定の幅からこの指定を行えばよいわけです。上述の雑誌風レイアウトは2の「各要素を細かくレイアウトする場合」の例に当たります。

FlexBoxとCSS Gridの謎の違い

画像を横並びにするときの高さが揃わないことがある

画像を横並びにしたときに、CSS Gridだど高さが揃わないことがあります。min-heightを指定すれば問題ありませんし、読み込み時のズレ防止のためにもheightを指定するのが推奨なので、そうすればよいのですが。

以下にデモを示します。CSS Gridに切り替えると画像の高さが揃わなくなります。ちなみに、align-items: center;にすると、FlexBoxでもmin-heightを指定しないと高さが揃わなくなります。

デモ

京都 横浜 吉祥寺 北海道 沖縄

画像の横に文字列を配置する時

次のような配置をしようとした場合に、Flexboxだと画像の幅がgapで設定した幅の分だけ表示されないことがあります。

この場合、CSS Gridを利用した方がよさそうです。

以下にデモを示しますが、このバグ、解消されているかもしれません。発生条件確認します。

デモ

吉祥寺

吉祥寺はどこかノスタルジックな雰囲気も感じられる街です。衣食住のいずれもお洒落なお店が揃いつつ、リーズナブルなお店もあり、住みたい街ランキングで長年上位に位置しています。

FlexBoxで配置が理屈通りにならないことがある

FlexBoxはどうもブラウザ側、端末側に配置に関するバグが残っている感じがします。

ひとつ間違いなさそうなものとして、writing-mode: vertical-rl;にしたときのiOSにおける配置の問題を見つけてまして、詳しくは次の記事でご紹介しています。

flexboxに関するiOSのバグと回避方法

まとめ

CSS GridとFlexBoxについて比較しました。それぞれのレイアウトをシミュレーションできるようにしましたので、徹底的に比較していただけるかと思います。もっとこうしてほしいなど、ご意見あれば(対応のお約束はできませんが・・)お気軽にお問い合わせください。

SEO対策、ホームページ制作のご依頼、ご相談に関するお問い合わせももちろん、お待ちしています!

著者のイメージ画像

BringFlower
稲田 高洋(Takahiro Inada)

2003年から大手総合電機メーカーでUXデザインプロセスの研究、実践。UXデザイン専門家の育成プログラム開発。SEOにおいても重要なW3Cが定めるWeb標準仕様策定にウェブアクセシビリティの専門家として関わる。2010~2018年に人間中心設計専門家を保有、数年間ウェブアクセシビリティ基盤委員も務める。その後、不動産会社向けにSaaSを提供する企業の事業開発部で複数サービスを企画、ローンチ。CMSを提供し1000以上のサイトを分析。顧客サポート、サイト運営にも関わる。
2022年3月にBringFlowerを開業し、SEOコンサル、デザイン、ウェブ制作を一手に受ける。グッドデザイン賞4件、ドイツユニバーサルデザイン賞2件、米国IDEA賞1件の受賞歴あり。
プロフィール詳細