2026年5月20日

2026年5月20日

WordPressのサイドバーをスティッキー(固定)にする方法

はじめに

サイドバーをスクロールに追従させる(スティッキー化)には、CSSの position: sticky を使うのが最もシンプルです。古いブラウザへの対応が必要な場合やより細かい制御が必要な場合はJavaScriptを併用します。

症状・原因

  • サイドバーが固定されずスクロールで見えなくなる
  • position: sticky を設定したが効かない
  • サイドバーが記事コンテンツより短い場合の挙動がおかしい
  • ヘッダーに被ってしまう

解決手順

ステップ1:CSSのposition:stickyで実装する

/* 子テーマの style.css に追加 */

/* サイドバーの親コンテナ */
.content-area {
    display: flex;
    align-items: flex-start; /* ← これが重要 */
    gap: 40px;
}

/* サイドバー本体 */
.widget-area {
    position: sticky;
    top: 80px; /* ヘッダーの高さ + 余白 */
    width: 300px;
    flex-shrink: 0;
    max-height: calc(100vh - 100px); /* 画面高さからヘッダー分を引く */
    overflow-y: auto; /* サイドバーが長い場合はスクロール */
}

/* メインコンテンツ */
.site-main {
    flex: 1;
    min-width: 0; /* flex内でのはみ出し防止 */
}

ステップ2:position:stickyが効かない場合の確認

/* position:stickyが効かない原因チェック */

/* NG: 親要素にoverflow:hiddenが設定されている */
.content-wrapper {
    overflow: hidden; /* ← これがあるとstickyが効かない */
}

/* OK: overflow を削除または auto に変更 */
.content-wrapper {
    overflow: visible; /* または削除 */
}

/* NG: 親要素に高さが設定されていない */
/* → align-items: flex-start を親に追加する(上記参照) */

/* 確認: DevToolsで .widget-area を選択 */
/* → Computed タブで position の値を確認 */
/* → 親要素に overflow:hidden/auto がないか確認 */

ステップ3:JavaScriptで実装する(細かい制御が必要な場合)

// js/sticky-sidebar.js
document.addEventListener('DOMContentLoaded', function () {
    const sidebar    = document.querySelector('.widget-area');
    const container  = document.querySelector('.content-area');
    const headerH    = document.querySelector('.site-header')?.offsetHeight || 60;
    const gap        = 20;
    const topOffset  = headerH + gap;

    if (!sidebar || !container) return;

    let lastScrollY  = window.scrollY;
    let sidebarTop   = sidebar.getBoundingClientRect().top + window.scrollY;

    function updateSidebar() {
        const scrollY        = window.scrollY;
        const containerBottom = container.getBoundingClientRect().bottom + scrollY;
        const sidebarBottom  = scrollY + topOffset + sidebar.offsetHeight;

        if (scrollY + topOffset >= sidebarTop) {
            // サイドバーが画面下に達したら止める
            if (sidebarBottom >= containerBottom) {
                sidebar.style.position = 'absolute';
                sidebar.style.top      = (containerBottom - sidebar.offsetHeight) + 'px';
            } else {
                sidebar.style.position = 'fixed';
                sidebar.style.top      = topOffset + 'px';
            }
        } else {
            sidebar.style.position = 'static';
        }

        lastScrollY = scrollY;
    }

    window.addEventListener('scroll', updateSidebar, { passive: true });
});

ステップ4:JavaScriptをfunctions.phpで読み込む

// 子テーマの functions.php
add_action('wp_enqueue_scripts', function(): void {
    // サイドバーが存在するページのみ読み込む
    if (is_singular() || is_archive() || is_home()) {
        wp_enqueue_script(
            'sticky-sidebar',
            get_stylesheet_directory_uri() . '/js/sticky-sidebar.js',
            [],
            wp_get_theme()->get('Version'),
            true
        );
    }
});

ステップ5:モバイルでスティッキーを解除する

/* モバイルではスティッキーを無効化 */
@media (max-width: 768px) {
    .widget-area {
        position: static; /* スティッキー解除 */
        width: 100%;
        max-height: none;
        overflow-y: visible;
    }

    .content-area {
        flex-direction: column; /* 縦並びに変更 */
    }
}

ステップ6:動作確認

# テーマのCSSが正しく読み込まれているか確認
wp eval "
global \$wp_styles;
wp_print_styles();
foreach (\$wp_styles->queue as \$handle) {
    if (strpos(\$handle, 'child') !== false) {
        echo \$handle . ': ' . \$wp_styles->registered[\$handle]->src . PHP_EOL;
    }
}"

# ページのHTML構造を確認
wp eval "echo get_template_part('sidebar') . PHP_EOL;" 2>/dev/null || echo "sidebar.phpを確認してください"

注意事項

  • position: sticky は親要素に overflow: hidden または overflow: auto が設定されていると機能しません
  • align-items: flex-start を親のFlexコンテナに設定しないと、サイドバーがメインコンテンツと同じ高さに引き伸ばされてstickyが効きません
  • top の値はサイトのヘッダー高さに合わせて調整してください

まとめ

スティッキーサイドバーはCSSの position: sticky と親要素の align-items: flex-start の組み合わせで実装できます。効かない場合は親要素の overflow 設定を確認してください。モバイルでは position: static に戻すことを忘れずに。

お気軽にご相談ください

お見積りへ お問い合わせへ