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 1fr
とrepeat(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-column
とgrid-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つの要素を親要素に対して上下中央揃えにしたい場合
- ブロック要素同士を横並びにしたい場合
- 要素同士に一定間隔を空けたい場合
CSS Gridを使うと良い場面
CSS Gridを使うべき場面もありますし、私は少なからず使っています。
以下のような用途では私はCSS Gridを用います。
- 画像などをグリッド表示する場合
- 各要素を細かくレイアウトする場合
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における配置の問題を見つけてまして、詳しくは次の記事でご紹介しています。
まとめ
CSS GridとFlexBoxについて比較しました。それぞれのレイアウトをシミュレーションできるようにしましたので、徹底的に比較していただけるかと思います。もっとこうしてほしいなど、ご意見あれば(対応のお約束はできませんが・・)お気軽にお問い合わせください。
SEO対策、ホームページ制作のご依頼、ご相談に関するお問い合わせももちろん、お待ちしています!