HTMLで2カラムレイアウトを作る方法|初心者でもできる基本とコツ

Web

Web制作を始めたばかりの人から、よくこんな相談をいただきます。

「ブログサイトのように、メインコンテンツの横にサイドバーを配置したい」
「2カラムレイアウトを作りたいけど、どの方法が一番良いの?」
「レスポンシブ対応も含めて、現代的な2カラムを作りたい」

2カラムレイアウトは、Webデザインの基本中の基本です。メインコンテンツとサイドバーを効果的に配置することで、情報を整理し、ユーザビリティを向上させることができます。

この記事では、HTML・CSSで2カラムレイアウトを作成する複数の方法を基本から応用まで、初心者にもわかりやすく解説します。

スポンサーリンク

2カラムレイアウトの基本概念

2カラムレイアウトとは

2カラムレイアウトとは、Webページを2つの縦の列(カラム)に分けて構成するレイアウト手法です。

一般的な構成パターン

パターン1: メインコンテンツ + サイドバー

┌─────────────┬─────────┐
│             │         │
│ メインコンテンツ │ サイドバー │
│   (70-80%)  │ (20-30%) │
│             │         │
└─────────────┴─────────┘

パターン2: サイドバー + メインコンテンツ

┌─────────┬─────────────┐
│         │             │
│ サイドバー │ メインコンテンツ │
│ (20-30%) │   (70-80%)  │
│         │             │
└─────────┴─────────────┘

2カラムレイアウトの用途

ブログ・メディアサイト

  • : メインコンテンツ(記事)
  • : サイドバー(カテゴリ、人気記事、広告など)

企業サイト

  • : ナビゲーションメニュー
  • : ページコンテンツ

ECサイト

  • : 商品カテゴリ、フィルター
  • : 商品一覧

Flexboxを使った2カラムレイアウト

基本的なFlexbox 2カラム

最もモダンで推奨される方法です。

HTML構造

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flexbox 2カラムレイアウト</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header class="header">
        <h1>サイトタイトル</h1>
        <nav>
            <ul>
                <li><a href="#">ホーム</a></li>
                <li><a href="#">サービス</a></li>
                <li><a href="#">お問い合わせ</a></li>
            </ul>
        </nav>
    </header>

    <main class="container">
        <article class="main-content">
            <h2>メインコンテンツ</h2>
            <p>ここにメインの内容が入ります。記事やページのメインコンテンツを配置します。</p>
            <p>Flexboxを使用することで、柔軟で保守しやすいレイアウトを作成できます。</p>
        </article>

        <aside class="sidebar">
            <h3>サイドバー</h3>
            <ul>
                <li><a href="#">カテゴリ1</a></li>
                <li><a href="#">カテゴリ2</a></li>
                <li><a href="#">カテゴリ3</a></li>
            </ul>
            
            <div class="widget">
                <h4>人気記事</h4>
                <ul>
                    <li><a href="#">記事タイトル1</a></li>
                    <li><a href="#">記事タイトル2</a></li>
                    <li><a href="#">記事タイトル3</a></li>
                </ul>
            </div>
        </aside>
    </main>

    <footer class="footer">
        <p>&copy; 2024 サンプルサイト</p>
    </footer>
</body>
</html>

CSS(基本版)

/* リセットCSS */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Helvetica Neue', Arial, sans-serif;
    line-height: 1.6;
    color: #333;
}

/* ヘッダー */
.header {
    background-color: #2c3e50;
    color: white;
    padding: 1rem;
}

.header h1 {
    margin-bottom: 0.5rem;
}

.header nav ul {
    list-style: none;
    display: flex;
    gap: 2rem;
}

.header nav a {
    color: white;
    text-decoration: none;
}

.header nav a:hover {
    text-decoration: underline;
}

/* メインコンテナ(Flexbox) */
.container {
    display: flex;
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem;
    gap: 2rem;
}

/* メインコンテンツ */
.main-content {
    flex: 2; /* 2の比率で拡大 */
    background-color: #fff;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.main-content h2 {
    margin-bottom: 1rem;
    color: #2c3e50;
}

.main-content p {
    margin-bottom: 1rem;
}

/* サイドバー */
.sidebar {
    flex: 1; /* 1の比率で拡大 */
    background-color: #f8f9fa;
    padding: 1.5rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.sidebar h3 {
    margin-bottom: 1rem;
    color: #2c3e50;
    border-bottom: 2px solid #3498db;
    padding-bottom: 0.5rem;
}

.sidebar ul {
    list-style: none;
    margin-bottom: 2rem;
}

.sidebar li {
    margin-bottom: 0.5rem;
}

.sidebar a {
    color: #3498db;
    text-decoration: none;
}

.sidebar a:hover {
    text-decoration: underline;
}

.widget {
    background-color: #fff;
    padding: 1rem;
    border-radius: 4px;
    margin-top: 1rem;
}

.widget h4 {
    margin-bottom: 0.5rem;
    color: #2c3e50;
}

/* フッター */
.footer {
    background-color: #34495e;
    color: white;
    text-align: center;
    padding: 1rem;
    margin-top: 2rem;
}

/* レスポンシブ対応 */
@media (max-width: 768px) {
    .container {
        flex-direction: column;
    }
    
    .main-content, .sidebar {
        flex: none;
    }
}

固定幅とflexibleな組み合わせ

サイドバー固定、メインコンテンツ可変

.container {
    display: flex;
    gap: 2rem;
}

.main-content {
    flex: 1; /* 残り全ての幅を使用 */
}

.sidebar {
    width: 300px; /* 固定幅 */
    flex-shrink: 0; /* 縮小を防ぐ */
}

メインコンテンツ固定、サイドバー可変

.container {
    display: flex;
    gap: 2rem;
}

.main-content {
    width: 800px; /* 固定幅 */
    flex-shrink: 0;
}

.sidebar {
    flex: 1; /* 残り全ての幅を使用 */
}

高度なFlexboxテクニック

等高カラム(高さを揃える)

.container {
    display: flex;
    align-items: stretch; /* デフォルトで等高 */
}

/* 内容量に関係なく両カラムの高さが揃う */

縦方向の配置制御

.container {
    display: flex;
    align-items: flex-start; /* 上揃え */
    /* align-items: center; 中央揃え */
    /* align-items: flex-end; 下揃え */
}

flex-wrapを使った折り返し

.container {
    display: flex;
    flex-wrap: wrap;
}

.main-content {
    flex: 2;
    min-width: 300px; /* 最小幅を設定 */
}

.sidebar {
    flex: 1;
    min-width: 200px;
}

CSS Gridを使った2カラムレイアウト

基本的なGrid 2カラム

CSS Gridは、より強力なレイアウトシステムです。

HTML構造

<div class="grid-container">
    <header class="header">ヘッダー</header>
    <main class="main-content">メインコンテンツ</main>
    <aside class="sidebar">サイドバー</aside>
    <footer class="footer">フッター</footer>
</div>

CSS(Grid版)

.grid-container {
    display: grid;
    grid-template-columns: 2fr 1fr; /* 2:1の比率 */
    grid-template-rows: auto 1fr auto;
    grid-template-areas: 
        "header header"
        "main sidebar"
        "footer footer";
    gap: 1rem;
    min-height: 100vh;
    max-width: 1200px;
    margin: 0 auto;
    padding: 1rem;
}

.header {
    grid-area: header;
    background-color: #2c3e50;
    color: white;
    padding: 1rem;
}

.main-content {
    grid-area: main;
    background-color: #fff;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.sidebar {
    grid-area: sidebar;
    background-color: #f8f9fa;
    padding: 1rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.footer {
    grid-area: footer;
    background-color: #34495e;
    color: white;
    text-align: center;
    padding: 1rem;
}

/* レスポンシブ対応 */
@media (max-width: 768px) {
    .grid-container {
        grid-template-columns: 1fr;
        grid-template-areas: 
            "header"
            "main"
            "sidebar"
            "footer";
    }
}

固定幅Gridレイアウト

.grid-container {
    display: grid;
    grid-template-columns: 250px 1fr; /* サイドバー250px固定 */
    gap: 2rem;
}

複雑なGridパターン

.grid-container {
    display: grid;
    grid-template-columns: 200px 1fr 200px; /* 3カラムベースの2カラム */
    grid-template-areas: 
        "nav main sidebar"
        "nav main sidebar";
}

.navigation {
    grid-area: nav;
}

.main-content {
    grid-area: main;
}

.sidebar {
    grid-area: sidebar;
}

従来のFloat方式(参考)

Float基本構造

現在は推奨されませんが、理解のために紹介します。

<div class="container">
    <div class="main-content">メインコンテンツ</div>
    <div class="sidebar">サイドバー</div>
    <div class="clearfix"></div>
</div>
.container {
    max-width: 1200px;
    margin: 0 auto;
}

.main-content {
    float: left;
    width: 70%;
    padding: 20px;
    background-color: #fff;
}

.sidebar {
    float: right;
    width: 28%;
    padding: 20px;
    background-color: #f8f9fa;
}

.clearfix {
    clear: both;
}

/* または、擬似要素を使用 */
.container::after {
    content: "";
    display: block;
    clear: both;
}

Floatの問題点

  1. レイアウトの複雑さ: clearfixが必要
  2. 等高カラムの困難さ: 高さを揃えるのが大変
  3. レスポンシブ対応の煩雑さ: メディアクエリでの調整が複雑

レスポンシブ2カラムレイアウト

モバイルファーストアプローチ

/* モバイル(デフォルト) */
.container {
    display: block;
}

.main-content, .sidebar {
    width: 100%;
    margin-bottom: 2rem;
}

/* タブレット以上 */
@media (min-width: 768px) {
    .container {
        display: flex;
        gap: 2rem;
    }
    
    .main-content {
        flex: 2;
        margin-bottom: 0;
    }
    
    .sidebar {
        flex: 1;
        margin-bottom: 0;
    }
}

/* デスクトップ */
@media (min-width: 1024px) {
    .container {
        max-width: 1200px;
        margin: 0 auto;
    }
}

ブレークポイント別最適化

/* スマートフォン(〜767px) */
@media (max-width: 767px) {
    .container {
        flex-direction: column;
        padding: 1rem;
    }
    
    .sidebar {
        order: -1; /* サイドバーを上に移動 */
    }
}

/* タブレット(768px〜1023px) */
@media (min-width: 768px) and (max-width: 1023px) {
    .container {
        padding: 1.5rem;
    }
    
    .main-content {
        flex: 1.5;
    }
    
    .sidebar {
        flex: 1;
    }
}

/* デスクトップ(1024px〜) */
@media (min-width: 1024px) {
    .container {
        padding: 2rem;
    }
    
    .main-content {
        flex: 2;
    }
    
    .sidebar {
        flex: 1;
    }
}

Container Queries(最新技術)

.container {
    container-type: inline-size;
}

@container (max-width: 600px) {
    .container {
        flex-direction: column;
    }
}

実用的な2カラムパターン集

ブログレイアウト

<div class="blog-container">
    <main class="blog-main">
        <article class="post">
            <header class="post-header">
                <h1>記事タイトル</h1>
                <div class="post-meta">
                    <time datetime="2024-01-15">2024年1月15日</time>
                    <span class="category">カテゴリ</span>
                </div>
            </header>
            <div class="post-content">
                <p>記事の内容...</p>
            </div>
            <footer class="post-footer">
                <div class="tags">
                    <span class="tag">タグ1</span>
                    <span class="tag">タグ2</span>
                </div>
            </footer>
        </article>
    </main>
    
    <aside class="blog-sidebar">
        <div class="widget search-widget">
            <h3>検索</h3>
            <form>
                <input type="search" placeholder="検索...">
                <button type="submit">検索</button>
            </form>
        </div>
        
        <div class="widget categories-widget">
            <h3>カテゴリ</h3>
            <ul>
                <li><a href="#">Web制作 (15)</a></li>
                <li><a href="#">デザイン (8)</a></li>
                <li><a href="#">プログラミング (12)</a></li>
            </ul>
        </div>
        
        <div class="widget popular-posts">
            <h3>人気記事</h3>
            <div class="popular-post">
                <img src="thumbnail1.jpg" alt="">
                <div class="post-info">
                    <h4><a href="#">人気記事タイトル1</a></h4>
                    <time>2024-01-10</time>
                </div>
            </div>
        </div>
    </aside>
</div>
.blog-container {
    display: flex;
    max-width: 1200px;
    margin: 0 auto;
    gap: 3rem;
    padding: 2rem;
}

.blog-main {
    flex: 2;
}

.post {
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    overflow: hidden;
    margin-bottom: 2rem;
}

.post-header {
    padding: 2rem 2rem 1rem;
    border-bottom: 1px solid #eee;
}

.post-header h1 {
    margin-bottom: 1rem;
    color: #2c3e50;
}

.post-meta {
    color: #666;
    font-size: 0.9rem;
}

.post-content {
    padding: 2rem;
    line-height: 1.8;
}

.post-footer {
    padding: 1rem 2rem 2rem;
}

.tags {
    display: flex;
    gap: 0.5rem;
}

.tag {
    background: #3498db;
    color: white;
    padding: 0.25rem 0.75rem;
    border-radius: 15px;
    font-size: 0.8rem;
}

.blog-sidebar {
    flex: 1;
}

.widget {
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    padding: 1.5rem;
    margin-bottom: 2rem;
}

.widget h3 {
    margin-bottom: 1rem;
    color: #2c3e50;
    border-bottom: 2px solid #3498db;
    padding-bottom: 0.5rem;
}

.search-widget form {
    display: flex;
    gap: 0.5rem;
}

.search-widget input {
    flex: 1;
    padding: 0.5rem;
    border: 1px solid #ddd;
    border-radius: 4px;
}

.search-widget button {
    padding: 0.5rem 1rem;
    background: #3498db;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

.categories-widget ul {
    list-style: none;
}

.categories-widget li {
    margin-bottom: 0.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid #eee;
}

.categories-widget a {
    color: #333;
    text-decoration: none;
}

.categories-widget a:hover {
    color: #3498db;
}

.popular-post {
    display: flex;
    gap: 1rem;
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid #eee;
}

.popular-post img {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: 4px;
}

.post-info h4 {
    margin-bottom: 0.25rem;
    font-size: 0.9rem;
}

.post-info a {
    color: #333;
    text-decoration: none;
}

.post-info a:hover {
    color: #3498db;
}

.post-info time {
    font-size: 0.8rem;
    color: #666;
}

ダッシュボードレイアウト

<div class="dashboard-container">
    <nav class="dashboard-nav">
        <h2>ダッシュボード</h2>
        <ul class="nav-menu">
            <li><a href="#" class="active">ダッシュボード</a></li>
            <li><a href="#">ユーザー管理</a></li>
            <li><a href="#">投稿管理</a></li>
            <li><a href="#">設定</a></li>
        </ul>
    </nav>
    
    <main class="dashboard-main">
        <header class="dashboard-header">
            <h1>ダッシュボード</h1>
            <div class="user-info">
                <span>管理者さん</span>
                <button class="logout-btn">ログアウト</button>
            </div>
        </header>
        
        <div class="dashboard-content">
            <div class="stats-grid">
                <div class="stat-card">
                    <h3>総ユーザー数</h3>
                    <div class="stat-number">1,234</div>
                </div>
                <div class="stat-card">
                    <h3>今月の投稿</h3>
                    <div class="stat-number">56</div>
                </div>
                <div class="stat-card">
                    <h3>ページビュー</h3>
                    <div class="stat-number">12,345</div>
                </div>
            </div>
            
            <div class="recent-activity">
                <h2>最近のアクティビティ</h2>
                <ul class="activity-list">
                    <li>新しいユーザーが登録しました</li>
                    <li>記事が投稿されました</li>
                    <li>コメントが追加されました</li>
                </ul>
            </div>
        </div>
    </main>
</div>
.dashboard-container {
    display: flex;
    min-height: 100vh;
}

.dashboard-nav {
    width: 250px;
    background: #2c3e50;
    color: white;
    padding: 2rem 0;
    flex-shrink: 0;
}

.dashboard-nav h2 {
    padding: 0 2rem;
    margin-bottom: 2rem;
    color: #ecf0f1;
}

.nav-menu {
    list-style: none;
}

.nav-menu li {
    margin-bottom: 0.5rem;
}

.nav-menu a {
    display: block;
    padding: 1rem 2rem;
    color: #bdc3c7;
    text-decoration: none;
    transition: all 0.3s ease;
}

.nav-menu a:hover,
.nav-menu a.active {
    background: #34495e;
    color: white;
    border-right: 3px solid #3498db;
}

.dashboard-main {
    flex: 1;
    background: #f8f9fa;
    display: flex;
    flex-direction: column;
}

.dashboard-header {
    background: white;
    padding: 1rem 2rem;
    border-bottom: 1px solid #dee2e6;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.dashboard-header h1 {
    color: #2c3e50;
}

.user-info {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.logout-btn {
    padding: 0.5rem 1rem;
    background: #e74c3c;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

.dashboard-content {
    flex: 1;
    padding: 2rem;
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}

.stat-card {
    background: white;
    padding: 1.5rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    text-align: center;
}

.stat-card h3 {
    color: #666;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}

.stat-number {
    font-size: 2rem;
    font-weight: bold;
    color: #3498db;
}

.recent-activity {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.recent-activity h2 {
    margin-bottom: 1rem;
    color: #2c3e50;
}

.activity-list {
    list-style: none;
}

.activity-list li {
    padding: 0.75rem 0;
    border-bottom: 1px solid #eee;
    color: #555;
}

パフォーマンスとアクセシビリティ

パフォーマンス最適化

CSSの最適化

/* 効率的なセレクタの使用 */
.container {
    display: flex; /* Flexboxは高パフォーマンス */
}

/* 避けるべき:複雑なセレクタ */
/* .container > .main-content:nth-child(2n+1) ~ .sidebar */

/* 推奨:シンプルなクラスセレクタ */
.main-content {
    /* ... */
}

レイアウトシフトの防止

.container {
    display: flex;
    min-height: 400px; /* 最小高さを設定 */
}

.sidebar {
    width: 300px; /* 明示的な幅指定 */
    flex-shrink: 0;
}

アクセシビリティ対応

セマンティックHTML

<div class="container">
    <main class="main-content" role="main" aria-label="メインコンテンツ">
        <article>
            <h1>記事タイトル</h1>
            <p>記事の内容...</p>
        </article>
    </main>
    
    <aside class="sidebar" role="complementary" aria-label="サイドバー">
        <nav aria-label="カテゴリナビゲーション">
            <h2>カテゴリ</h2>
            <ul>
                <li><a href="#">カテゴリ1</a></li>
                <li><a href="#">カテゴリ2</a></li>
            </ul>
        </nav>
    </aside>
</div>

スキップリンク

<a href="#main-content" class="skip-link">メインコンテンツへスキップ</a>

<div class="container">
    <main id="main-content" class="main-content">
        <!-- メインコンテンツ -->
    </main>
    <aside class="sidebar">
        <!-- サイドバー -->
    </aside>
</div>
.skip-link {
    position: absolute;
    top: -40px;
    left: 6px;
    background: #000;
    color: #fff;
    padding: 8px;
    text-decoration: none;
    border-radius: 4px;
    z-index: 1000;
}

.skip-link:focus {
    top: 6px;
}

フォーカス管理

/* フォーカス可能要素の見た目を改善 */
a:focus,
button:focus,
input:focus {
    outline: 2px solid #3498db;
    outline-offset: 2px;
}

/* フォーカストラップ対応 */
.container:focus-within .sidebar {
    /* サイドバー内の要素にフォーカスがある時の表示 */
}

よくある問題と解決方法

等高カラムの実現

問題:カラムの高さが揃わない

/* 解決方法1: Flexbox(推奨) */
.container {
    display: flex;
    align-items: stretch; /* デフォルトで等高 */
}

/* 解決方法2: CSS Grid */
.container {
    display: grid;
    grid-template-columns: 2fr 1fr;
    /* 自動的に等高になる */
}

/* 解決方法3: 最小高さの設定 */
.main-content,
.sidebar {
    min-height: 500px;
}

レスポンシブ対応の問題

問題:モバイルでレイアウトが崩れる

/* 解決方法:適切なブレークポイント設定 */
.container {
    display: flex;
    flex-wrap: wrap;
}

@media (max-width: 768px) {
    .container {
        flex-direction: column;
    }
    
    /* サイドバーを上に移動 */
    .sidebar {
        order: -1;
    }
    
    /* パディングを調整 */
    .main-content,
    .sidebar {
        padding: 1rem;
    }
}

コンテンツ量による問題

問題:片方のカラムが長すぎる

/* 解決方法1: スティッキーサイドバー */
.sidebar {
    position: sticky;
    top: 20px;
    align-self: flex-start;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
}

/* 解決方法2: 最大高さの制限 */
.sidebar {
    max-height: 600px;
    overflow-y: auto;
}

パフォーマンス問題

問題:レイアウトシフトが発生

/* 解決方法:明示的なサイズ指定 */
.container {
    display: flex;
    min-height: 100vh; /* 最小高さを確保 */
}

.sidebar {
    width: 300px; /* 固定幅 */
    flex-shrink: 0; /* 縮小防止 */
}

/* 画像のアスペクト比保持 */
.sidebar img {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9; /* モダンブラウザ */
}

実践的なカスタマイズ例

スライダー付きサイドバー

<div class="container">
    <button class="sidebar-toggle" aria-label="サイドバーの表示切替">
        ☰
    </button>
    <main class="main-content">
        <h1>メインコンテンツ</h1>
        <p>内容...</p>
    </main>
    <aside class="sidebar" id="sidebar">
        <button class="sidebar-close" aria-label="サイドバーを閉じる">
            ×
        </button>
        <h2>サイドバー</h2>
        <nav>
            <ul>
                <li><a href="#">リンク1</a></li>
                <li><a href="#">リンク2</a></li>
            </ul>
        </nav>
    </aside>
</div>
.container {
    display: flex;
    position: relative;
}

.sidebar-toggle {
    display: none;
    position: fixed;
    top: 1rem;
    left: 1rem;
    z-index: 1001;
    background: #3498db;
    color: white;
    border: none;
    padding: 0.5rem;
    border-radius: 4px;
    cursor: pointer;
}

.sidebar {
    width: 300px;
    background: #f8f9fa;
    transition: transform 0.3s ease;
    flex-shrink: 0;
}

.sidebar-close {
    display: none;
    float: right;
    background: none;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
}

@media (max-width: 768px) {
    .sidebar-toggle {
        display: block;
    }
    
    .sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        z-index: 1000;
        transform: translateX(-100%);
        box-shadow: 2px 0 10px rgba(0,0,0,0.1);
    }
    
    .sidebar.active {
        transform: translateX(0);
    }
    
    .sidebar-close {
        display: block;
    }
    
    .main-content {
        width: 100%;
        margin-left: 0;
    }
}
// JavaScript for sidebar toggle
document.addEventListener('DOMContentLoaded', function() {
    const toggle = document.querySelector('.sidebar-toggle');
    const close = document.querySelector('.sidebar-close');
    const sidebar = document.querySelector('.sidebar');
    
    toggle.addEventListener('click', function() {
        sidebar.classList.add('active');
    });
    
    close.addEventListener('click', function() {
        sidebar.classList.remove('active');
    });
    
    // クリック外しで閉じる
    document.addEventListener('click', function(e) {
        if (!sidebar.contains(e.target) && !toggle.contains(e.target)) {
            sidebar.classList.remove('active');
        }
    });
});

アニメーション付きレイアウト

.container {
    display: flex;
    transition: all 0.3s ease;
}

.main-content {
    flex: 1;
    transition: margin-left 0.3s ease;
}

.sidebar {
    width: 300px;
    transform: translateX(0);
    transition: transform 0.3s ease;
}

/* サイドバー非表示状態 */
.container.sidebar-hidden .sidebar {
    transform: translateX(-100%);
}

.container.sidebar-hidden .main-content {
    margin-left: -300px;
}

/* ホバーエフェクト */
.sidebar:hover {
    box-shadow: 2px 0 15px rgba(0,0,0,0.1);
}

.main-content {
    transition: background-color 0.3s ease;
}

.main-content:hover {
    background-color: #f9f9f9;
}

開発効率化のTips

CSSフレームワークとの組み合わせ

Bootstrap 5での2カラム

<div class="container-fluid">
    <div class="row">
        <main class="col-lg-8">
            メインコンテンツ
        </main>
        <aside class="col-lg-4">
            サイドバー
        </aside>
    </div>
</div>

Tailwind CSSでの2カラム

<div class="flex flex-col lg:flex-row gap-6 max-w-6xl mx-auto p-6">
    <main class="lg:w-2/3">
        <div class="bg-white rounded-lg shadow-md p-6">
            メインコンテンツ
        </div>
    </main>
    <aside class="lg:w-1/3">
        <div class="bg-gray-50 rounded-lg shadow-md p-6">
            サイドバー
        </div>
    </aside>
</div>

CSS Modulesでの管理

/* Layout.module.css */
.container {
    display: flex;
    gap: 2rem;
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem;
}

.mainContent {
    flex: 2;
    background: white;
    border-radius: 8px;
    padding: 2rem;
}

.sidebar {
    flex: 1;
    background: #f8f9fa;
    border-radius: 8px;
    padding: 1.5rem;
}

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

Sassでの効率化

// _variables.scss
$sidebar-width: 300px;
$gap-size: 2rem;
$breakpoint-mobile: 768px;

// _mixins.scss
@mixin flex-container($direction: row, $gap: $gap-size) {
    display: flex;
    flex-direction: $direction;
    gap: $gap;
}

@mixin responsive-mobile {
    @media (max-width: $breakpoint-mobile) {
        @content;
    }
}

// layout.scss
.container {
    @include flex-container();
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem;
    
    @include responsive-mobile {
        flex-direction: column;
        padding: 1rem;
    }
}

.main-content {
    flex: 2;
    background: white;
    border-radius: 8px;
    padding: 2rem;
}

.sidebar {
    width: $sidebar-width;
    flex-shrink: 0;
    background: #f8f9fa;
    border-radius: 8px;
    padding: 1.5rem;
    
    @include responsive-mobile {
        width: 100%;
    }
}

まとめ

HTMLとCSSで2カラムレイアウトを作成する方法について、包括的に解説しました。

重要なポイント

  • Flexbox: 最も推奨される現代的な手法
  • CSS Grid: より複雑なレイアウトに適している
  • レスポンシブ対応: モバイルファーストでの設計
  • アクセシビリティ: セマンティックHTMLとARIA属性の活用

手法別の使い分け

  • Flexbox: シンプルな2カラム、動的なコンテンツサイズ
  • CSS Grid: 複雑なレイアウト、固定的な構造
  • Float: レガシーサポート(非推奨)
  • 情報の整理されたユーザーフレンドリーなWebサイトを作成できるようになるはずです!

コメント

タイトルとURLをコピーしました