【CSS実践入門 #3】Flexboxレイアウト入門 - 3カラムレイアウトを実装する

パソコ(ブログアシスタント) パソコ

こんにちは!パソコです🔥 この記事、最後まで読んでいってね!

Flexboxレイアウト入門 - 現代的なレイアウト手法をマスターしよう

これまでCSSの基礎とセレクタを学んできました。今回は現代のウェブ開発で欠かせない「Flexbox」について、実際の3カラムレイアウト実装を通じて詳しく学んでいきます。

🎯 今回学ぶこと

  • Flexboxの基本概念と仕組み
  • 3カラムレイアウトの実装方法
  • レスポンシブ対応の実践
  • 実際のウェブサイトでの適用例

📚 Flexboxとは?

Flexbox(フレキシブルボックス) は、要素を柔軟に配置・整列するためのCSSレイアウト手法です。従来のfloatやpositionより直感的で強力な機能を提供します。

Flexboxの基本構造

1
2
3
4
5
<div class="flex-container">
    <div class="flex-item">アイテム1</div>
    <div class="flex-item">アイテム2</div>
    <div class="flex-item">アイテム3</div>
</div>
1
2
3
.flex-container {
    display: flex; /* Flexboxを有効化 */
}

主軸と交差軸

Flexboxには2つの軸があります:

  • 主軸(Main Axis): アイテムが配置される主要な方向
  • 交差軸(Cross Axis): 主軸に垂直な方向
1
2
3
4
5
.flex-container {
    display: flex;
    flex-direction: row; /* 主軸の方向:横(デフォルト) */
    /* flex-direction: column; 縦方向 */
}

🔧 Flexboxプロパティ詳解

親要素(Flexコンテナ)のプロパティ

display

1
2
3
4
.container {
    display: flex;        /* ブロックレベルのFlexコンテナ */
    /* display: inline-flex; インラインのFlexコンテナ */
}

flex-direction(配置方向)

1
2
3
4
5
6
.container {
    flex-direction: row;         /* 左から右(デフォルト) */
    /* flex-direction: row-reverse;  右から左 */
    /* flex-direction: column;       上から下 */
    /* flex-direction: column-reverse; 下から上 */
}

justify-content(主軸方向の配置)

1
2
3
4
5
6
7
8
.container {
    justify-content: flex-start;    /* 左寄せ(デフォルト) */
    /* justify-content: flex-end;     右寄せ */
    /* justify-content: center;       中央寄せ */
    /* justify-content: space-between; 両端揃え */
    /* justify-content: space-around;  均等配置 */
    /* justify-content: space-evenly;  完全均等配置 */
}

align-items(交差軸方向の配置)

1
2
3
4
5
6
7
.container {
    align-items: stretch;        /* 高さを揃える(デフォルト) */
    /* align-items: flex-start;    上揃え */
    /* align-items: flex-end;      下揃え */
    /* align-items: center;        中央揃え */
    /* align-items: baseline;      ベースライン揃え */
}

flex-wrap(折り返し)

1
2
3
4
5
.container {
    flex-wrap: nowrap;          /* 折り返さない(デフォルト) */
    /* flex-wrap: wrap;            折り返す */
    /* flex-wrap: wrap-reverse;    逆方向に折り返す */
}

gap(アイテム間のスペース)

1
2
3
4
5
6
.container {
    gap: 20px;                  /* 全方向に20px */
    /* gap: 20px 10px;            縦20px、横10px */
    /* row-gap: 20px;             行間のみ */
    /* column-gap: 10px;          列間のみ */
}

子要素(Flexアイテム)のプロパティ

flex-grow(伸張率)

1
2
3
4
5
6
7
.item-1 {
    flex-grow: 1; /* 残りスペースを1の比率で取得 */
}

.item-2 {
    flex-grow: 2; /* 残りスペースを2の比率で取得 */
}

flex-shrink(収縮率)

1
2
3
4
.item {
    flex-shrink: 1; /* スペースが足りない時に1の比率で縮小 */
    /* flex-shrink: 0;  縮小しない */
}

flex-basis(ベースサイズ)

1
2
3
4
5
.item {
    flex-basis: 200px; /* 基本サイズを200pxに設定 */
    /* flex-basis: auto;  要素の幅/高さを使用(デフォルト) */
    /* flex-basis: 0;     内容のサイズを無視 */
}

flex(短縮記法)

1
2
3
4
5
.item {
    flex: 1;           /* flex: 1 1 0%; と同じ */
    /* flex: 0 1 auto;    flex-grow: 0, flex-shrink: 1, flex-basis: auto */
    /* flex: 2 0 100px;   flex-grow: 2, flex-shrink: 0, flex-basis: 100px */
}

align-self(個別の交差軸配置)

1
2
3
.special-item {
    align-self: flex-end; /* この要素だけ下揃え */
}

🏗️ 実践:3カラムレイアウトの実装

実際のブログサイトで使用する3カラムレイアウトを構築してみましょう。

HTML構造

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!DOCTYPE html>
<html>
<head>
    <title>技術ブログサイト</title>
    <!-- メタタグなど -->
</head>
<body>
    <!-- ヘッダー -->
    <header class="site-header">
        <!-- ヘッダーコンテンツ -->
    </header>
    
    <!-- メインコンテナ -->
    <div class="main-container">
        <!-- 左サイドバー -->
        <aside class="sidebar sidebar-left">
            <div class="sidebar-content">
                <div class="widget">
                    <h3 class="widget-title">📚 最新トピックス</h3>
                    <!-- ウィジェットコンテンツ -->
                </div>
                
                <div class="widget">
                    <h3 class="widget-title">🛠️ 技術記事ガイド</h3>
                    <!-- ウィジェットコンテンツ -->
                </div>
            </div>
        </aside>
        
        <!-- メインコンテンツ -->
        <main class="main-content">
            <!-- メインコンテンツ -->
            <div class="article-content">
                <h1>記事タイトル</h1>
                <p>記事の内容...</p>
            </div>
        </main>
        
        <!-- 右サイドバー -->
        <aside class="sidebar sidebar-right">
            <div class="sidebar-content">
                <div class="widget">
                    <h3 class="widget-title">🏆 アクセスランキング</h3>
                    <!-- ウィジェットコンテンツ -->
                </div>
                
                <div class="widget">
                    <h3 class="widget-title">📁 カテゴリー</h3>
                    <!-- ウィジェットコンテンツ -->
                </div>
            </div>
        </aside>
    </div>
    
    <!-- フッター -->
    <footer class="site-footer">
        <!-- フッターコンテンツ -->
    </footer>
</body>
</html>

CSS実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/* メインコンテナ:Flexboxレイアウト */
.main-container {
    display: flex;                /* Flexboxを有効化 */
    max-width: 1200px;           /* 最大幅を制限 */
    margin: 0 auto;              /* 中央寄せ */
    gap: 20px;                   /* アイテム間のスペース */
    padding: 20px;               /* 外側の余白 */
    min-height: calc(100vh - 140px); /* ヘッダー・フッター分を除いた高さ */
}

/* 左サイドバー */
.sidebar-left {
    flex: 0 0 280px;            /* 固定幅280px、伸縮なし */
    order: 1;                   /* 表示順序:1番目 */
}

/* メインコンテンツ */
.main-content {
    flex: 1;                    /* 残りのスペースをすべて使用 */
    min-width: 0;               /* 要素が縮小できるようにする */
    order: 2;                   /* 表示順序:2番目 */
}

/* 右サイドバー */
.sidebar-right {
    flex: 0 0 320px;            /* 固定幅320px、伸縮なし */
    order: 3;                   /* 表示順序:3番目 */
}

/* サイドバー共通スタイル */
.sidebar {
    background-color: #f8f9fa;
    border-radius: 8px;
    padding: 0;                 /* paddingはsidebar-contentで設定 */
}

.sidebar-content {
    padding: 20px;
}

/* ウィジェット */
.widget {
    background: white;
    border-radius: 6px;
    padding: 20px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.widget:last-child {
    margin-bottom: 0;
}

.widget-title {
    color: #2c3e50;
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 16px 0;
    padding-bottom: 8px;
    border-bottom: 2px solid #3498db;
}

/* メインコンテンツのスタイル */
.main-content {
    background: white;
    border-radius: 8px;
    padding: 30px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

📱 レスポンシブ対応

タブレット表示(1024px以下)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@media (max-width: 1024px) {
    .main-container {
        gap: 15px;
        padding: 15px;
    }
    
    /* 左サイドバーを非表示 */
    .sidebar-left {
        display: none;
    }
    
    /* 右サイドバーの幅を調整 */
    .sidebar-right {
        flex: 0 0 280px;
    }
    
    /* メインコンテンツの調整 */
    .main-content {
        padding: 20px;
    }
}

モバイル表示(768px以下)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@media (max-width: 768px) {
    .main-container {
        flex-direction: column;    /* 縦方向に配置変更 */
        gap: 15px;
        padding: 10px;
    }
    
    /* すべての要素を全幅に */
    .sidebar-left,
    .sidebar-right,
    .main-content {
        flex: none;
        width: 100%;
        order: initial;           /* 順序をリセット */
    }
    
    /* 表示順序を調整 */
    .main-content {
        order: 1;                /* メインコンテンツを最初に */
    }
    
    .sidebar-right {
        order: 2;                /* 右サイドバーを2番目に */
    }
    
    /* パディングを調整 */
    .main-content,
    .sidebar-content {
        padding: 15px;
    }
    
    /* ウィジェットを簡略化 */
    .widget {
        padding: 15px;
        margin-bottom: 15px;
    }
    
    .widget-title {
        font-size: 14px;
        margin-bottom: 12px;
    }
}

小型モバイル(480px以下)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@media (max-width: 480px) {
    .main-container {
        padding: 5px;
        gap: 10px;
    }
    
    .main-content,
    .sidebar-content {
        padding: 10px;
    }
    
    .widget {
        padding: 12px;
        margin-bottom: 12px;
    }
}

🎨 Flexboxの実践テクニック

1. 完璧な中央寄せ

1
2
3
4
5
6
.center-container {
    display: flex;
    justify-content: center;    /* 水平方向の中央寄せ */
    align-items: center;        /* 垂直方向の中央寄せ */
    min-height: 300px;
}

2. カードレイアウト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.card-container {
    display: flex;
    flex-wrap: wrap;           /* 折り返しを許可 */
    gap: 20px;
    justify-content: space-between;
}

.card {
    flex: 0 1 calc(33.333% - 14px); /* 3カラム(gap分を引く) */
    min-width: 280px;          /* 最小幅を設定 */
}

/* 2カラム表示 */
@media (max-width: 768px) {
    .card {
        flex: 0 1 calc(50% - 10px);
    }
}

/* 1カラム表示 */
@media (max-width: 480px) {
    .card {
        flex: 1 1 100%;
    }
}

3. ヘッダーナビゲーション

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
.header-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 20px;
    height: 60px;
}

.nav-brand {
    flex: 0 0 auto;           /* 固定サイズ */
}

.nav-menu {
    display: flex;
    gap: 20px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.nav-actions {
    flex: 0 0 auto;           /* 固定サイズ */
    display: flex;
    gap: 10px;
}

4. フッターレイアウト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
.footer-content {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 30px;
}

.footer-section {
    flex: 1 1 250px;          /* 最小幅250px、伸縮可能 */
    min-width: 250px;
}

@media (max-width: 768px) {
    .footer-content {
        flex-direction: column;
    }
    
    .footer-section {
        flex: none;
        text-align: center;
    }
}

🔧 JavaScriptでの動的制御

サイドバーの表示切り替え

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<div class="main-container" id="main-container">
    <aside class="sidebar sidebar-left" id="left-sidebar">
        <!-- 左サイドバーコンテンツ -->
    </aside>
    
    <main class="main-content">
        <!-- メインコンテンツ -->
    </main>
    
    <aside class="sidebar sidebar-right" id="right-sidebar">
        <!-- 右サイドバーコンテンツ -->
    </aside>
</div>

<button onclick="toggleSidebar('left')">左サイドバー切り替え</button>
<button onclick="toggleSidebar('right')">右サイドバー切り替え</button>

JavaScript制御

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function toggleSidebar(side) {
    const sidebar = document.getElementById(`${side}-sidebar`);
    const container = document.getElementById('main-container');
    
    if (sidebar.style.display === 'none') {
        sidebar.style.display = 'block';
        container.classList.remove(`hide-${side}`);
    } else {
        sidebar.style.display = 'none';
        container.classList.add(`hide-${side}`);
    }
}

対応するCSS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/* 通常の3カラム */
.main-container {
    display: flex;
    gap: 20px;
}

/* 左サイドバー非表示時 */
.main-container.hide-left .main-content {
    margin-left: 0;
}

/* 右サイドバー非表示時 */
.main-container.hide-right .main-content {
    margin-right: 0;
}

🚀 次回予告

次回は「レスポンシブデザイン完全ガイド」について学びます:

  • メディアクエリの詳細
  • ブレークポイント設計
  • モバイルファーストアプローチ
  • 画像の最適化
  • パフォーマンス考慮

📝 今回のまとめ

  1. Flexboxは現代的なレイアウト手法で直感的
  2. 3カラムレイアウトはflex比率で効率的に実装可能
  3. レスポンシブ対応はflex-directionとorderで実現
  4. JavaScriptと組み合わせて動的なレイアウト制御が可能

Flexboxをマスターすれば、複雑なレイアウトも簡潔に実装できるようになります!


💡 質問やフィードバックがあれば、コメント欄やTwitter(@firebird19245)でお気軽にどうぞ!

シリーズ記事

  • 【第1回】CSSの基礎知識
  • 【第2回】CSSセレクタとカスケード
  • 【第3回】Flexboxレイアウト入門(この記事)
  • 【第4回】レスポンシブデザイン完全ガイド(次回)
  • 【第5回】JavaScript入門 - インタラクティブなウェブサイト作り
この記事をシェアX Facebook はてブ
技術ネタ、趣味や備忘録などを書いているブログです
Hugo で構築されています。
テーマ StackJimmy によって設計されています。