【JS&CSS】途中からフワッと表れて追従する固定ヘッダーの作り方

以下のように画面をスクロールすると、ヘッダーがフワッと表示されて追従(トップに固定)するヘッダーの作り方を紹介します。(JavaScriptとCSSを使います。)

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

スクロールできます。スクロールできます。

なお、CSSのみでヘッダーを追従・固定することもでき、以下記事で実装例やコードを公開しています。

目次

HTML / CSS / JavaScript コード

<header id="main-header">
  <div class="logo">仮ロゴ</div>
  <!-- PC用表示 -->
  <nav class="pc-menu">
    <ul>
      <li><a href="#">Menu 1</a></li>
      <li><a href="#">Menu 2</a></li>
      <li><a href="#">Menu 3</a></li>
    </ul>
  </nav>
  <!-- モバイル用表示 -->
  <div class="mobile-menu">
    <div class="line"></div>
    <div class="line"></div>
    <div class="line"></div>
  </div>
</header>

<header id="fixed-header">
  <div class="logo">仮ロゴ</div>
  <!-- PC用表示 -->
  <nav class="pc-menu">
    <ul>
      <li><a href="#">Menu 1</a></li>
      <li><a href="#">Menu 2</a></li>
      <li><a href="#">Menu 3</a></li>
    </ul>
  </nav>
  <!-- モバイル用表示 -->
  <div class="mobile-menu">
    <div class="line"></div>
    <div class="line"></div>
    <div class="line"></div>
  </div>
</header>
<main>
  <!-- ページの内容 -->
</main>

実装のポイント

最初に表示するヘッダーと、スクロール時に追従するヘッダーの2つを設置する

実装例では、以下の2つのヘッダー要素を配置しています。

<header id="main-header">
    ~~~~~~~~~~~~~~~~~~~~
</header>

<header id="fixed-header">
    ~~~~~~~~~~~~~~~~~~~~
</header>

id="main-header"は最初から表示しておくヘッダーで、id="fixed-header"id="main-header"が見えなくなるまでスクロールされたら表示するヘッダーです。こちらのヘッダーには以下のようなCSSプロパティが設定されています。

#fixed-header {
  /* 画面上部に固定表示するプロパティ */
  position: fixed;
  top: 0;
  left: 0;

  /* 非表示(透明)にするプロパティ */
  opacity: 0;

  /* ヘッダーを上から表示させるために要素を少し上に配置しておくプロパティ */
  transform: translateY(-100%);

  /* フワッと表示させるためのプロパティ */
  transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;
}

スクロールしたとき、条件に応じてヘッダーをフワッと表示

画面をスクロールしたときのイベントハンドラーscrollを使用し、スクロールした位置によってヘッダーid="fixed-header"の表示・非表示を切り替えます。

window.addEventListener('scroll', function() {
    // スクロール時の処理
});

まず、ページのスクロール位置を変数scrollTopに格納します。

let scrollTop = window.scrollY || document.documentElement.scrollTop;

window.scrollY がサポートされていない古いブラウザの場合、document.documentElement.scrollTop が代わりに使われます

次にスクロールダウン時とアップ時に分けて処理を行います。

if (scrollTop > lastScrollTop) {
  // スクロールダウン時
  if (scrollTop > mainHeader.clientHeight) {
    // 表示位置をトップに移動して表示
    fixedHeader.style.transform = 'translateY(0)';
    fixedHeader.style.opacity = '1';
  }
} else {
  // スクロールアップ時
  if (scrollTop <= mainHeader.clientHeight) {
    // 表示位置を上方に戻して非表示
    fixedHeader.style.transform = 'translateY(-100%)';
    fixedHeader.style.opacity = '0';
  }
}
  • スクロールダウン時scrollToplastScrollTop より大きい場合
    • このとき、scrollTopmainHeader.clientHeight (ヘッダーid="main-header"のY軸方向の位置)を超えている場合(つまりヘッダーが見えなくなったとき)、fixedHeader を表示します。
  • スクロールアップ時scrollToplastScrollTop より小さい場合
    • このとき、scrollTopmainHeader.clientHeight (ヘッダーid="main-header"のY軸方向の位置)以下に戻った場合(つまりヘッダーが表示されたとき)、fixedHeader を非表示にします。

最後に、現在のスクロール位置を lastScrollTop に保存して、次回のスクロールイベントで比較できるようにします。

lastScrollTop = scrollTop;

(おまけ)PCとモバイルでメニュー表示を変える

本筋とは関係ないですが、ウィンドウ幅に応じてメニュー表示を変更するにはメディアクエリを利用します。
(実装例では、ウィンドウ幅が広い時にナビメニュー、ウィンドウ幅が狭い時にハンバーガーメニューを表示しています。)

この辺りも合わせて実装できれば、よりヘッダーらしくなりますね。
メディアクエリとハンバーガーメニューについてはそれぞれ別記事で紹介していますので、合わせてご覧ください。


当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次