NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

注目のタグ

    【CSS】レイアウトを組むとき使うのはFlexbox?CSS Grid?

    はじめに

    初めまして、2025年度新入社員の岡嵜健太です。
    現在私は、HTMLやCSS、(極まれにJS)を用いてflexboxの便利さに感動しながらモック作成やエンハンス業務などを行っています。

    さて、早速ですが皆さんは以下のようなレイアウトを組むときはどのように実装しますか?

    Flexbox?CSS Grid?Marginで調整? 私はFlexbox大好き人間でしたのでなんとなくFlexboxを使いがちでした。←よくない
    そんな私が、業務で1からCSS Gridを学び、Flexbox・CSS Grid大好き人間になったので、今回はFlexboxとCSS Gridを上手に使いこなすためにそれぞれの特徴や考え方についてまとめました。

    1. Flexboxって?CSS Gridって?

    Flexboxとは

    「並べ方の制御」に強いレイアウト手段で親要素にdisplay:flexを指定し、その直下の子要素を柔軟に並べたり整列させたりするcssのレイアウト記法です。

    CSS Gridとは

    「配置の制御」に強いレイアウト手段で、親要素に display: grid を指定し、 行(row)と列(column)の構造を定義して、その直下の子要素を2次元的に配置・レイアウトできる CSS のレイアウト記法です。

    2.考え方について

    ただ、「並べ方の制御」と「配置の制御」といわれてもいまいちピンとこない方もいるかと思います。
    そこでもう少しだけわかりやすく説明していきたいと思います。

    Flexboxの考え方

    Flexboxは中身となるコンテンツが決まっていてそのコンテンツをどのように並べていくかというコンテンツ駆動型の考え方です。

    具体的にイメージをするのであれば、体育の準備体操が近しいです。
    例えば30名の生徒が準備体操をするシーンをイメージしてください。

    この場合は生徒(コンテンツ)は30名で並べ方は

    • 出席番号順で縦並び
    • 背の順で横並び
    • 背の順で縦並び、かつ横との間隔を広く

    など色々あると思います。
    この「30人をどう並べるか」この考え方がFlexboxの考え方です。

    次にCSS Gridについてです。

    CSS Gridは先にどのように配置するかを決定し、区切られた領域にコンテンツを配置していくというレイアウト駆動型の考え方です。

    こちらも具体的にイメージしてみましょう。
    今回イメージするのは将棋盤です。将棋盤はすでに9×9の81マスで構成(レイアウト)されており、そのマス目に沿って駒を配置していきますね。

    • 3行目の全列のマスに「歩兵」を配置する
    • 1行目の5列目に「王将」を配置する
    • 1行目の4列目と6列目に「金将」を配置する

    など、「駒をどこに配置するか」この考え方がCSS Gridの考え方です。

    3.得意と苦手

    ここまででFlexboxとCSS Gridのイメージや考え方は何となくできたかと思います。
    では次はそれぞれが何が得意で何が苦手か見ていきましょう。

    並べ方が1方向のとき

    Flexbox:○
    →シンプルな並べ方において輝く
    →整列(justify / align)が圧倒的に簡単で、HTML 構造に左右されにくい。

    CSS Grid:△
    →オーバースペック、逆に複雑になってしまうかも

    複雑なレイアウト

    例 縦横2方向・大きさが違う

    Flexbox:×
    →管理が大変、display:flexだらけに...

    CSS Grid:○
    → grid-area 指定で「◯◯を左上・◯◯を右下」など配置位置を明確に制御できる

    レスポンシブ設計

    Flexbox:○

    CSS Grid:○

    →両者言わずもがな

    4.実践編

    どのような場面でどちらを使うのか、コードと一緒に見てみましょう。(カラーやコンテンツの内容など一部省略されています。)

    Flexboxが向いているシーン

    次にFlexboxが向いている場面の紹介です。

    シンプルな縦・横並び

    <div class="flex-container">
        <img src="sample.jpg" alt="">
        <img src="sample.jpg" alt="">
        <img src="sample.jpg" alt="">
        <img src="sample.jpg" alt="">
    </div>
    
    .flex-container {
        display: flex;
        justify-content: center;
        gap: 10px;
    }
    

    数が不確定で折り返しがある要素

    <ul class="flex-container">
      <li class="tag">サンプル</li>
      <li class="tag">サンプル</li>
    以下省略
    </ul>
    
    .flex-container{
      display: flex;
      flex-wrap: wrap;
      gap: 8px 10px;
      padding: 50px;
      margin: 0;
      list-style: none;
    }
    
    .tag {
      padding: 6px 12px;
      font-size: 13px;
      border: 1px solid #e5e7eb;
      border-radius: 8px;
      background: #f8fafc;
      color: #374151;
      white-space: nowrap;
    }
    

    Gridが向いているシーン

    タイル風のレイアウト

    <div class="grid-container">
           <div class="tile col-3 row-1">1</div>
           <div class="tile col-1 row-1">2</div>
           <div class="tile col-1 row-2">3</div>
           <div class="tile col-1 row-1">4</div>
           <div class="tile col-1 row-2">5</div>
           <div class="tile col-1 row-1">6</div>
           <div class="tile col-2 row-1">7</div>
    </div>
    
    .grid-container {
        padding: 50px;
        display: grid;
        gap: 15px;
        grid-template-columns: 1.5fr 1fr 1.5fr;
        grid-template-rows: 1fr 1fr 1fr;
    }
    .col-1 {
        grid-column: span 1;
    }
    .col-2 {
        grid-column: span 2;
    }
    .col-3 {
        grid-column: span 3;
    }
    .row-1 {
        grid-row: span 1;
    }
    .row-2 {
        grid-row: span 2;
    }
    .row-3 {
        grid-row: span 3;
    }
    

    CSS Gridといえばのレイアウトですね。

    カードレイアウト

    <div class="grid-container">
         <div class="card">
              <a href="####">
                   <div class="title">タイトル</div>
                   <div class="label">ラベル</div>
                   <div class="text">
                       テキストテキストテキストテキストテキストテキストテキスト
                    テキストテキストテキストテキストテキストテキストテキスト
                    テキストテキストテキストテキストテキストテキストテキスト</div>
                   <div class="date">yyyy/mm/dd</div>
              </a>
         </div>
    </div>
    
    .grid-container {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
      gap: 16px;
      padding: 50px;
    }
    
    .card a {
      display: contents;
    }
    
    .card {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
      gap: 8px;
    }
    

    Flexboxでも比較的簡単に近しい実装はできます。ただ、カードの子要素の高さを揃えたい場合はCSS GridのSubgridを使うとよいでしょう。

    ページ全体のレイアウト

    <body>
        <header class="header">
            <!-- 内容省略 -->
        </header>
    
        <main class="grid-container">
            <nav>
                <!-- 内容省略 -->
            </nav>
    
            <article>
                <!-- 内容省略 -->
            </article>
    
            <aside>
                <!-- 内容省略 -->
            </aside>
        </main>
    
        <footer class="footer">
            <!-- 内容省略 -->
        </footer>
    </body>
    
    .grid-container {
      display: grid;
      grid-template-columns: 240px 1fr 280px;
      gap: 24px;
      align-items: start;
      max-width: 1200px;
      margin-inline: auto;
      padding: 24px;
      box-sizing: border-box;
    }
    
    .grid-container>nav {
      grid-column: 1;
    }
    
    .grid-container>article {
      grid-column: 2;
    }
    
    .grid-container>aside {
      grid-column: 3;
    }
    

    ページ全体のレイアウトもGridでやった方が視覚的にわかりやすいですね。

    5.まとめ

    FlexboxとCSS Gridは、それぞれが得意な場面と活かすべき考え方を持った別々のレイアウト手段です。

    • Flexbox は「並べ方」に強い 1 次元のレイアウトツール
      → コンテンツをどう整列させるか、どう並べるかを柔軟に操作できる

    • CSS Grid は「配置」に強い 2 次元のレイアウトツール
      → 行と列の構造を先に決めて、その上に要素を自在に配置できる

    また、CSS Gridを使ってレイアウトを組んでそのレイアウトの中でFlexboxを使って並べるなど、CSS GridとFlexboxを柔軟に組み合わせて使用することもできます。

    どちらを使えば良いか迷ったら、まずは

    「これは並べたいのか?配置したいのか?」

    を元に考えてみてはいかがでしょうか。

    参考資料

    Flexbox: developer.mozilla.org

    CSS Grid: developer.mozilla.org

    執筆者:岡嵜 健太 フロントエンジニア