聖杯レイアウト(Holy Grail Layout)

Flexbox で実装するまとめノート

聖杯レイアウトとは

ヘッダー・フッターが上下に固定され、中央に3カラム(左ナビ・メインコンテンツ・右サイドバー)が横並びになるWebページの古典的なレイアウトパターンです。

かつては float と負のマージンを駆使した複雑な実装が必要でしたが、Flexboxの登場により非常にシンプルに実現できるようになりました。

<構造>
                      +---------------------------+
                      |          Header           |
                      +------+------------+-------+
                      | Left |    Main    | Right |
                      | Nav  |  Content   | Aside |
                      +------+------------+-------+
                      |          Footer           |
                      +---------------------------+

HTMLの構造

<header>
  <div class="header-inner">
    <div class="logo"><a href="/">サイト名</a></div>
    <nav class="header-nav">
      <ul>
        <li><a href="#">ホーム</a></li>
        <li><a href="#">サービス</a></li>
        <li><a href="#">ブログ</a></li>
      </ul>
    </nav>
  </div>
</header>

<div class="wrapper">
  <nav class="side-nav">...</nav>
  <main>メインコンテンツ</main>
  <aside>サイドバー</aside>
</div>

<footer>フッター</footer>

CSSの実装ポイント

1. bodyを縦方向のFlexコンテナにする

body {
  min-height: 100vh;       /* 最低でも画面全体の高さを確保 */
  display: flex;
  flex-direction: column;  /* 縦方向に並べる */
  width: 100%;
  max-width: 1200px;       /* 広くなりすぎない上限 */
  margin: 0 auto;          /* 中央寄せ */
}

height ではなく min-height を使うことで、コンテンツが増えても自然に広がります。

2. wrapperで3カラムを横並びにする

.wrapper {
  display: flex;
  flex: 1;  /* 残りの高さをすべて使う */
}

3. 各カラムの幅指定

.side-nav {
  width: 150px;
  flex-shrink: 0;  /* 幅が縮まないように固定 */
}
main {
  flex: 1;          /* 余った幅をすべて使う */
}
aside {
  width: 200px;
  flex-shrink: 0;
}

4. ヘッダーナビとサイドナビを区別する 重要

nav タグに直接スタイルを当てると、ヘッダー内のナビとサイドのナビ両方に影響してしまいます。クラスで区別することが重要です。

.header-nav { /* ヘッダー用 */ }
.side-nav    { /* サイドバー用 */ }

スマホ対応(レスポンシブ)

@media screen and (max-width: 900px) {
  body {
    width: 100%;
  }
  .wrapper {
    flex-direction: column; /* 横並び→縦並びに切り替え */
  }
  .side-nav, aside {
    width: 100%;             /* サイドバーを全幅に */
  }
  main {
    order: -1;              /* メインを最上部に移動 */
  }
}

order: -1 を使うことで、HTMLの順序を変えずにメインコンテンツをスマホ表示で最上部に移動できます。

学んだことまとめ

ポイント 内容
min-height vs height コンテンツが増えても崩れないよう min-height を使う
flex: 1 余った空間を自動で埋める
flex-shrink: 0 サイドバーが縮まないよう固定する
クラスで区別 nav タグの競合を防ぐため .side-nav などクラスを使う
order プロパティ HTMLを変えずに表示順を変更できる
max-width PCで左右の余白が広くなりすぎないよう上限を設ける
CSSコメント // は使えない。/* */ を使う
box-sizing: border-box paddingやborderを幅に含めてレイアウト崩れを防ぐ