脱・レイアウト迷子!FlexboxとGridを使いこなして「崩れない」Webサイトを作る現場の技術

目次

プロパティが多すぎて覚えられない

「ねえ、なんでfloat: leftしてるのに親要素の高さが消えるの? clearfixって何? おまじない?」
「要素を上下中央に配置したいだけなのに、なんでこんなに苦労しなきゃいけないの?」

もしあなたが今、Web制作の学習をしていて、こんな風にモニターに向かって悪態をついたことがあるなら、正直に言います。
あなたは、めちゃくちゃ運がいいです。

私がWeb業界に入った15年前、レイアウトを組むというのは「ブラウザとの戦争」でした。
要素を横並びにするだけで、バグだらけのfloatを使い、意味不明なネガティブマージンを駆使し、IE6(インターネットエクスプローラー6)というラスボスと毎晩戦い続けていました。
「ピクセルが1pxズレる」という理由だけで、徹夜でCSSを書き直したことも一度や二度じゃありません。

でも今はどうでしょう。
FlexboxCSS Gridという、神が与えたもうた最強の武器があります。
これさえ使いこなせれば、横並びも、上下中央揃えも、複雑な雑誌のようなレイアウトも、たった数行のコードで実現できてしまう。

ただ、ここで新たな問題が起きているのを、メンターとして何百人もの生徒を見てきて感じています。
「FlexboxとGrid、どっちを使えばいいかわからない問題」です。
プロパティが多すぎて覚えられない、思った通りの挙動をしてくれない、スマホで見たら崩れている…。

教科書的なプロパティの羅列はしません。それはMDN(公式ドキュメント)を見れば書いてあるから。
その代わり、現場のエンジニアが「どういう思考プロセスでレイアウトを決めているか」「実案件で頻出するパターン」、そして「絶対にやってはいけないアンチパターン」を、泥臭い実体験を交えて語り尽くします。

これを読み終わる頃には、あなたはCSSのレイアウトで迷子になることはなくなっているはずです。
コーヒーでも飲みながら、じっくり付き合ってください。

散らかったデスクで、崩れたレイアウトが表示されたモニターを見つめながら頭を抱えているエンジニアの線画イラスト

レイアウトの歴史を知ると「ありがたみ」が分かる

いきなりコードの話をする前に、少しだけ昔話をさせてください。
「なんでそんな話?」と思うかもしれませんが、これを知っていると、FlexboxやGridが「何を解決するために生まれたのか」が腑に落ちるからです。

暗黒のfloat時代

昔は、要素を横並びにするために float というプロパティを使っていました。
これ、本来は「画像にテキストを回り込ませるため」の機能なんですよ。それを無理やりレイアウトに使っていた。
だから、親要素の高さが消滅したり、フッターが変な位置に浮き上がってきたり、レイアウト崩れのオンパレードでした。
それを防ぐために clearfix という、魔術的なコードをCSSに仕込んでいたんです。

display: inline-block の台頭

次に流行ったのが display: inline-block です。
これはこれで、コード内の「改行」が「隙間」として画面に表示されてしまうという、謎の仕様に苦しめられました。
要素をピッタリくっつけたいのに、なぜか4pxくらいの隙間が空く。これを消すために、親要素のフォントサイズを0にするという、狂気じみたハックが横行していました。

そして伝説へ… FlexboxとGridの登場

そんなカオスな世界に終止符を打ったのが、FlexboxとGridです。
これらは、最初から「レイアウトを組むこと」を目的に作られた仕様です。
だから、バグ技みたいなことをしなくても、直感的に、かつ堅牢にレイアウトが組める。
私らベテラン勢からすれば、これらが使えるようになった瞬間は、まさに「産業革命」でした。

Flexboxは「数珠つなぎ」の1次元レイアウト

まず最初にマスターすべきは、間違いなくFlexbox(Flexible Box Layout)です。
現場での使用頻度は、体感で8割を超えます。

Flexboxの本質は「軸」の制御

Flexboxを理解する上で一番大事なのは、「1本の軸(Axis)に沿って要素を並べる」というイメージを持つことです。
横一列に並べるか、縦一列に並べるか。基本はこれだけです。

.container {
  display: flex;
}

親要素(コンテナ)にこれを書くだけで、子要素(アイテム)たちは強制的に横並びになります。
ここで初心者が混乱するのが、justify-contentalign-items です。
「どっちがどっちだっけ?」って、現場でもよく聞かれます。

  • justify-content: 主軸(並んでいる方向)の配置
  • align-items: 交差軸(並んでいる方向と直角の方向)の配置

デフォルトでは「主軸=横方向」なので、justify-content は横の位置合わせ、align-items は縦の位置合わせになります。
でも、flex-direction: column; で縦並びに変えると、この軸も回転するので役割が逆転します。
ここを「横・縦」で覚えているとパニックになるので、「流れている方向・それと垂直な方向」でイメージするのがコツです。

現場で頻出!「両端揃え」の魔術

Webサイトのヘッダーを見てください。左にロゴがあって、右にナビゲーションメニューがあるパターン、よくありますよね?
これを float でやろうとすると大変でしたが、Flexboxなら一撃です。

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

space-between。これこそがFlexbox最強の呪文です。
最初と最後の要素を端っこに押し付けて、間のスペースを自動で計算してくれる。
レスポンシブで画面幅が変わっても、勝手に調整してくれます。

陥りやすい「子要素潰れ」の罠

Flexboxを使っていて、「あれ? 画像の比率がおかしくなった?」とか「テキストが勝手に改行されちゃった?」という経験はありませんか?
Flexboxには、「親要素の幅に収まるように、子要素を無理やり縮める」というお節介機能(flex-shrink)がデフォルトでONになっています。

例えば、アイコンとテキストを横並びにしたい時。
テキストが長くなると、アイコンがギュッと押し潰されて、楕円形になってしまう。
これを防ぐには、アイコン側にこう書きます。

.icon {
  flex-shrink: 0;
}

「お前は絶対に縮むなよ」という命令です。
これ、地味ですが現場では必須のテクニックです。特にスマホ表示の調整で頻発します。

ホワイトボードに描かれたFlexboxの軸の図を指差しながら、後輩エンジニアに熱心に説明している様子の線画イラスト

CSS Gridは「方眼紙」の2次元レイアウト

次にCSS Gridです。
Flexboxが「数珠つなぎ」なら、Gridは「方眼紙(グリッド)に要素を配置していく」イメージです。
縦と横、2つの軸を同時に制御できるのが最大の特徴です。

Gridが最強なのは「全体レイアウト」

「ヘッダー、サイドバー、メインコンテンツ、フッター」みたいな、ページ全体のレイアウトを組む時、Gridの右に出るものはありません。

.container {
  display: grid;
  grid-template-columns: 200px 1fr;
  grid-template-rows: auto 1fr auto;
}

このように、「縦にどう分割するか」「横にどう分割するか」を親要素で一括管理できます。
Flexboxだと、HTMLの構造(divの入れ子)を工夫しないと実現できないレイアウトも、GridならHTML構造を変えずにCSSだけで配置を変えられます。
これの何が嬉しいかって、「スマホとPCでHTMLの順番を変えずに、見た目の配置だけガラッと変えられる」ことです。SEO的にもHTML構造は変えたくないので、これは大きなメリットです。

魔法の単位「fr」

Gridを使うなら、fr(フラクション)という単位を愛してください。
これは「余ったスペースを配分する」という単位です。

grid-template-columns: 1fr 2fr;
と書けば、画面幅に関わらず、常に「1 : 2」の比率で分割してくれます。
calc(33.333% - 10px) みたいな面倒な計算をしていた時代は終わったのです。

ギャップ(gap)こそ正義

Flexboxでも最近使えるようになりましたが、元々はGridの特権だった gap プロパティ。
要素間の余白を指定するだけのプロパティですが、これが革命的でした。
昔は margin-right: 20px; を指定して、一番右の要素だけ last-child { margin-right: 0; } で打ち消す…なんて不毛なことをやっていました。

.grid-container {
  display: grid;
  gap: 20px;
}

これだけで、要素の間だけに20pxの隙間が入ります。外側には入りません。
神ですか? はい、神です。
この gap のおかげで、コーディングの速度は倍になったと言っても過言じゃありません。

FlexboxとGrid、どっちを使うべき?現場の判断基準

「機能は分かったけど、結局どっちを使えばいいの?」
これは本当によく聞かれる質問です。
私の(というか多くのエンジニアの)判断基準はシンプルです。

  1. Flexboxを使う場面
    • ボタンを横並びにしたい
    • アイコンとテキストを並べたい
    • ヘッダーのメニュー
    • 「1行、または1列」で完結する小さなレイアウト
  2. Gridを使う場面
    • 画像ギャラリー(タイル状の配置)
    • ページ全体の大枠のレイアウト
    • 縦横の位置関係を厳密に揃えたい場合
    • 「2次元」の広がりを持つ大きなレイアウト

迷ったらFlexboxから始めろ

極論を言うと、GridでできることはFlexbox(と複雑なネスト)でもできます。
逆に、Flexboxの方が直感的で扱いやすいケースが多いです。
なので、初心者のうちは「基本はFlexbox、どうしても複雑なタイル配置が必要な時だけGrid」というスタンスで十分戦えます。

実際、私の書くコードを見返しても、display: flex の登場回数は display: grid の10倍くらいあります。
Gridは強力すぎるがゆえに、単純な横並びに使うとコードが冗長になりがちなんですよね。

PCモニターに表示された複雑なWebサイトのレイアウト構造を、FlexboxとGridの領域に色分けして分析している様子の線画イラスト

レスポンシブ対応の勘所|メディアクエリとの共闘

今のWeb制作で「スマホ対応」は必須です。
FlexboxとGridを使えば、レスポンシブ対応も劇的に楽になります。

Flexboxでスマホ対応:方向を変えるだけ

PCでは横並び、スマホでは縦並び。これ、一番多いパターンですよね。

.card-list {
  display: flex;
}

@media (max-width: 768px) {
  .card-list {
    flex-direction: column;
  }
}

たったこれだけです。flex-directionrow(横)から column(縦)に変えるだけ。
これで、横に並んでいたカードたちが、スマホでは縦に積み重なります。

Gridでスマホ対応:列数を変えるだけ

Gridの場合はもっとスマートです。

.grid-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* PCは3列 */
}

@media (max-width: 768px) {
  .grid-list {
    grid-template-columns: 1fr; /* スマホは1列 */
  }
}

これだけで、PCでは3カラム、スマホでは1カラムになります。
さらに auto-fitminmax を組み合わせると、メディアクエリすら書かずにレスポンシブ対応ができたりします(呪文みたいになるのでここでは割愛しますが、興味があったらググってみてください)。

実践!上下中央揃えの「聖杯」

CSSレイアウトにおいて、長年人類を苦しめてきた難題があります。
それが「上下中央揃え」です。
「要素を画面のど真ん中に置く」。ただそれだけのために、昔のエンジニアはテーブルレイアウトを使ったり、position: absolutetransform を駆使したりしてきました。

でも今は、たった3行です。

.parent {
  display: flex; /* または grid */
  justify-content: center;
  align-items: center; /* Gridなら place-items: center; */
}

これで終わりです。
初めてこれを知った時、あまりの簡単さに感動して涙が出そうになりました。
ログイン画面のフォームをど真ん中に置くのも、ヒーローイメージのキャッチコピーをど真ん中に置くのも、もう怖くありません。

現場で起きる「レイアウト崩れ」あるあると解決策

便利なFlexboxとGridですが、万能ではありません。
現場でよく遭遇するトラブルと、その解決策を共有します。

1. テキストが長すぎてレイアウトが壊れる

運用に入ってから、クライアントが想定の3倍くらいの長さの見出しを入れてきて、レイアウトが崩壊する。これ、日常茶飯事です。
Flexboxの子要素は、中身が増えると頑張って広がろうとします。
解決策は、min-width: 0; を指定すること。
これを指定すると、「縮める限界」のリミッターが解除されて、正しく縮んでくれるようになります。Flexboxのバグっぽい挙動に対抗する必須テクニックです。

2. IE11で表示が崩れている

かつての宿敵、Internet Explorer。
FlexboxやGridは、IE11だと挙動が怪しかったり、そもそもGridが完全には動かなかったりしました。
ですが、朗報です。2022年6月、IEは正式にサポート終了しました。
今の案件では「IEは非対応です」と胸を張って言えます(一部の官公庁案件などを除く…)。
もしクライアントに「IEで見れないんだけど」と言われたら、「Microsoftが使うなと言っています」と優しく教えてあげましょう。これだけでCSSの記述量は半分になります。

3. 高さ(height)が合わない

Flexboxで横並びにしたカード、中身のテキスト量が違うと高さがバラバラになりますよね。
でもデフォルト(align-items: stretch)なら、高さは揃うはずなんです。
揃わない原因の9割は、子要素に height: 100%; を書き忘れているか、孫要素への継承ができていないかです。
Flexboxは「直下の子要素」にしか効きません。孫要素の高さを揃えたいなら、子要素にも display: flex をかけて入れ子構造にする必要があります。
「迷ったらFlexboxの中にFlexboxを入れる」。これで大体解決します。

深夜のオフィスで、検証ツール(DevTools)の画面を食い入るように見つめながら、バグの原因を探っている様子の線画イラスト

独学では気づけない「クラス設計」の重要性

FlexboxやGridを覚えると、楽しくてついHTMLに直接スタイルを書きたくなるかもしれません(Tailwind CSSのように)。
でも、保守性を考えるなら「クラス設計」は避けて通れません。

コンテナとラッパーの使い分け

現場では、レイアウトを管理する用の div と、中身のコンテンツを入れる div を明確に分けます。

<div class="card-list-container"> <!-- ここでGridやFlexを指定 -->
  <div class="card"> <!-- ここにカードのデザインを指定 -->
    ...
  </div>
</div>

「装飾」と「配置」を混ぜないこと。
これが混ざると、「カードのデザインを使い回したいのに、変なマージンが付いてて使いにくい!」という事態になります。
「配置用の親箱」と「装飾用の子箱」。この意識を持つだけで、コードの品質はグッと上がります。

スキルを「お金」に変えるためのポートフォリオ戦略

ここまで技術的な話をしてきましたが、このスキルをどうやって副業や転職に繋げるか。
ポートフォリオを作る際に、FlexboxとGridをどうアピールするかのアドバイスです。

「レスポンシブ完全対応」は最強のアピール

ポートフォリオサイトを作る時、PC表示だけでなく、スマホ表示、タブレット表示での崩れがないかを徹底的にチェックしてください。
採用担当者やクライアントは、意外とスマホであなたのサイトを見ています。
そこで横スクロールが発生していたり、文字が重なっていたりしたら、その時点で「不採用」ボックス行きです。
逆に、FlexboxとGridを駆使して、どのデバイスでも美しく表示されていれば、それだけで「実務を分かっている」と評価されます。

模写コーディングで「構造」を見抜く目を養う

練習としておすすめなのが、有名なWebサイトの「模写」です。
AirbnbやApple、Pinterestなどのサイトを見て、「ここはFlexboxだな」「ここはGridだな」と推測しながらコードを書いてみる。
そしてChromeの検証ツールで答え合わせをする。
これを繰り返すと、Webサイトを見た瞬間に、頭の中でワイヤーフレーム(骨組み)が浮かび上がるようになります。
この「透視能力」がついたら、あなたはもう初心者卒業です。

カフェでノートPCを開き、有名なWebサイトのデザインを模写コーディングしながら、構造を分析している様子の線画イラスト

FAQ|よくある質問に答えます

Q. floatはもう覚えなくていいですか?
A. 新規構築なら覚えなくていいです。ただし、5年以上前に作られたサイトの改修案件だと、まだ現役で動いていることがあります。「昔はこういう書き方をしていたんだな」と、歴史の授業として知っておく程度でOKです。

Q. GridがあればFlexboxはいらないのでは?
A. いえ、共存します。ページ全体の大枠はGrid、その中のナビゲーションやボタン配置はFlexbox、というふうに使い分けるのがベストプラクティスです。適材適所です。

Q. CSSフレームワーク(Bootstrapなど)は使ったほうがいい?
A. 便利ですが、中身は結局FlexboxとGridです。基礎を理解せずにフレームワークを使うと、ちょっとしたカスタマイズで詰みます。まずは素のCSS(Vanilla CSS)で書けるようになってから、時短のためにフレームワークを使うのが正しい順序です。

Q. 縦書きレイアウトはどうすればいい?
A. 日本語特有の「縦書き」。これも writing-mode: vertical-rl; というプロパティを使えばCSSだけで可能です。Flexboxと組み合わせれば、縦書きサイトのレイアウトも組めますよ。

エンジニアとしての「レイアウト力」は一生の武器になる

CSSの仕様は年々進化していますが、FlexboxとGridの登場以降、レイアウトの基本概念は安定しました。
つまり、今この2つをマスターしておけば、今後10年は食いっぱぐれない「基礎体力」が身につくということです。

窓から朝日が差し込む部屋で、完成した美しいレスポンシブサイトが表示されたモニターを満足げに見つめるエンジニアの線画イラスト

私がまだ駆け出しの頃、先輩エンジニアに言われた言葉があります。
「デザインカンプを見た瞬間に、頭の中でHTML構造とCSSプロパティが組み立てられるようになれ」

最初は「そんなの無理だろ」と思いましたが、FlexboxとGridを理解した今なら分かります。
Webサイトは魔法でできているわけじゃありません。すべては「箱」の積み重ねであり、ルールの集合体なんです。

思い通りに要素が並んだ時の、あの「カチッ」とハマる快感。
パズルのピースが埋まった時のような気持ち良さ。
これを味わえるようになると、CSSを書くのが楽しくて仕方なくなります。

もし今、レイアウトが崩れてイライラしているなら、それはあなたが成長している証拠です。
諦めずに、検証ツールとにらめっこしてみてください。
そのバグを解決した数だけ、あなたはプロのエンジニアに近づいています。

さあ、エディタを開いて、世界一美しいレイアウトを作りに行きましょう。
display: flex; とタイプする準備はできましたか?

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いたエンジニア

金城 美咲のアバター 金城 美咲 フロントエンドエンジニア

フロントエンド領域に強く、UIの細部にまでこだわるデザイナー気質のエンジニア。React・Vueを扱い、モダン開発に柔軟に対応。人当たりがよく、相談しやすい雰囲気を持つ。休日はカフェ巡りやガジェット研究で新しい刺激を得ることが多い。

目次