スクロールに応じてヘッダーを表示・非表示にする方法

CSS、JavaScript

WebサイトのデザインやUI/UXを改善する上で、スクロールに応じたヘッダーの表示・非表示は、訪問者の利便性や視覚的な体験を向上させるために非常に役立ちます。この記事では、スクロールに応じてヘッダーを動的に表示・非表示にするための実装方法を解説します。今回の例では、JavaScriptとCSSを活用して、ページスクロールの方向に基づいてヘッダーの表示を切り替えます。

完成イメージ

  • ユーザーが下にスクロールするとヘッダーが非表示になります。
  • ユーザーが上にスクロールするとヘッダーが再び表示されます。
  • スマートフォンサイズでは常にヘッダーが表示されるように設定します。

See the Pen ScrollHeader by kasasagi_kmnmc (@kasasagi_kmnmc) on CodePen.

実装手順

HTML構造

まず、基本的なHTML構造を作成します。ヘッダーにはナビゲーションリンクが含まれ、スクロールして各セクションに移動することができます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テストサイト</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header id="header" class="hidden" role="banner">
        <h1>ウェブサイトのタイトル</h1>
        <nav aria-label="メインナビゲーション">
            <ul>
                <li><a href="#sectionA">セクションA</a></li>
                <li><a href="#sectionB">セクションB</a></li>
                <li><a href="#sectionC">セクションC</a></li>
            </ul>
        </nav>
    </header>

    <div class="section" id="sectionA">
        <h2>セクション A</h2>
        <p class="scroll-instruction">下へスクロールすると、ヘッダーが非表示になります。<br>上にスクロールすると、ヘッダーが表示されます。</p>
    </div>

    <div class="section" id="sectionB">セクション B</div>
    <div class="section" id="sectionC">セクション C</div>
  
    <script src="script.js"></script>
</body>
</html>

CSSでヘッダーのスタイルを設定

次に、CSSを使ってヘッダーとセクションのスタイルを設定します。特に、スクロールによってヘッダーの表示・非表示を滑らかにするためのトランジションを設定しています。

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: Arial, sans-serif;
}

header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background-color: white;
    padding: 10px;
    text-align: center;
    opacity: 0;
    transition: opacity 0.3s ease, transform 0.3s ease;
    z-index: 1000;
}

.hidden {
    transform: translateY(-100%);
}

.visible {
    opacity: 1;
    transform: translateY(0);
}

.section {
    height: 1000px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2rem;
    color: white;
}

#sectionA {
    background-color: #3498db;
}

#sectionB {
    background-color: #e74c3c;
}

#sectionC {
    background-color: #2ecc71;
}

JavaScriptでスクロールイベントを処理

最後に、JavaScriptを使ってスクロールイベントに応じてヘッダーを表示・非表示にします。スクロール位置を取得し、スクロール方向に応じてヘッダーを制御する関数を作成します。

let lastScrollTop = 0; // 最後のスクロール位置
const header = document.getElementById('header');
const scrollThreshold = 100; // ヘッダーが消えるしきい値(ピクセル)

// 初期表示でヘッダーを表示
header.classList.add('visible');
header.classList.remove('hidden');

function handleScroll() {
    const currentScroll = window.pageYOffset || document.documentElement.scrollTop;

    if (window.innerWidth >= 768) { // スマートフォンサイズの場合は処理を実行しない
        if (currentScroll > lastScrollTop && currentScroll > scrollThreshold) {
            // スクロールダウン時(しきい値を超えた場合)
            header.classList.remove('visible');
            header.classList.add('hidden');
        } else if (currentScroll < lastScrollTop) {
            // スクロールアップ時
            header.classList.remove('hidden');
            header.classList.add('visible');
        }
    }

    lastScrollTop = currentScroll <= 0 ? 0 : currentScroll; // 新しいスクロール位置を記録
}

// ウィンドウのリサイズ時にも処理を行う
window.addEventListener('resize', function() {
    if (window.innerWidth < 768) {
        // スマートフォンサイズではヘッダーを表示
        header.classList.remove('visible', 'hidden');
        header.classList.add('visible');
    }
});

// スクロールイベントを追加
window.addEventListener('scroll', function() {
    handleScroll();
});

コードの解説

HTMLの構造

  • <header>タグ内にナビゲーションメニューを配置。
  • 各セクションにスクロールできるリンクを持たせています。

CSSのスタイル

  • headerには固定位置(fixed)を指定し、スクロールに応じて表示・非表示を切り替えるためのトランジションを設定。
  • .hiddenクラスと.visibleクラスでヘッダーの状態を制御し、transformを用いて滑らかに動かしています。

JavaScriptのスクロール処理

  • handleScroll()関数で、ユーザーのスクロール方向を検知し、スクロールダウン時にヘッダーを隠し、スクロールアップ時に表示。
  • スマートフォンサイズ(幅768px未満)では常にヘッダーを表示するように、resizeイベントも追加。

まとめ

今回紹介した実装方法を使うことで、ユーザーが快適にコンテンツを閲覧できるよう、スクロールに応じてヘッダーを動的に表示・非表示にすることができます。特に、デスクトップではページを大きくスクロールすることが多いので、この機能はデザインの一貫性を保ちながら、ナビゲーションの邪魔を最小限に抑えることができます。

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