FirstLayout

固定ヘッダーやナビを下スクロール時に隠し、上スクロール時に表示する方法

動作

サイト上部に固定したヘッダーやナビなどが、下にスクロールすると消え、上にスクロールすると現れる実装方法の紹介です。

jQuery を使わず素の JavaScript で、かつ window.requestAnimationFrame() メソッドを使います。サイトが遅く重くならず、スピードが犠牲になりません。また、スムーズなアニメーションを表現できます。

実装後の動作は、このようなものです。サイト上部に、高さ 56px・背景色が赤のヘッダーを作っています。そのヘッダーが、下スクロール時に消え、上スクロール時に現れます。

HTML

今回は、ヘッダーを例とします。

HTML は、非常に単純なものです。

<header id="header">サイト名やナビなどを書く</header>

requestAnimationFrame() を使った JavaScript

次は JavaScript です。requestAnimationFrame() を使い、スクロールイベントを設定します。

let offset = 0;
let lastPosition = 0;
let ticking = false;
const header = document.getElementById('header');
const height = 56;

const onScroll = () => {
  if (lastPosition > height) {
    if (lastPosition > offset) {
      header.classList.add('head-animation');
    } else {
      header.classList.remove('head-animation');
    }
    offset = lastPosition;
  }
};

document.addEventListener('scroll', () => {
  lastPosition = window.scrollY;
  if (!ticking) {
    window.requestAnimationFrame(() => {
      onScroll();
      ticking = false;
    });
    ticking = true;
  }
});

参考

コードを説明します。

const target = document.getElementById('header');

4 行目で、対象の要素の id を指定します。今回は <header> の id を指定しています。

const height = 56;

5 行目は、対象の要素が隠れ始める位置の指定です。56 であれば、サイトの上部から 56px スクロールした地点から要素が隠れます。

0 の指定も可能ですが、アニメーションが性急に感じるかもしれません。対象の要素の高さと同じ値の指定がおすすめです。

また、下にスクロールしても、ある程度の位置まで要素を隠したくない場合があります。その場合には、400 など少し多めの任意の値を指定します。

target.classList.add('head-animation');

7 行目から 16 行目は、スクロール時の処理の設定です。そのうち 10 行目で、下にスクロールしている時に、対象の要素の class に head-animation を追加しています。

target.classList.remove('head-animation');

12 行目で、上にスクロールしている時は、対象の要素の class から head-animation を削除しています。

offset = lastPosition;

14 行目は、スクロール量の更新です。

18 行目から 27 行目は、requestAnimationFrame() の設定です。MDN のやり方をそのまま真似ています。元ネタの Leaner, Meaner, Faster Animations with requestAnimationFrame で、スクロールイベントをそのまま使うべきではない理由をご覧いただけます。

transform を使った CSS

あとは CSS を指定すれば完成します。CSS の一例は、下記のとおりです。

#header {
  background: #fff;
  box-shadow: 0 4px 8px -3px rgba(17, 17, 17, .06);
  height: 56px;
  position: fixed;
  top: 0;
  transition: .3s cubic-bezier(.4, 0, .2, 1);
  width: 100%;
  z-index: 199999;
}

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

対象の要素に position: fixed;top: 0; を指定し、サイト上部に固定します。

そして、JavaScript で追加する class の head-animation に、transform: translateY(-100%); を指定します。これで下にスクロール時は、対象の要素が上に消えていきます。

要素の高さを使った top: -56px; でも同じ表現はできますが、GPU アクセラレーションが可能な transform での指定がおすすめです。ブラウザの負荷を抑えられる上に、よりアニメーションが滑らかになります。

メニュー 閉じる 検索 記事を読む Facebook Twitter はてなブックマーク Pocket LINE ダウンロード 全ての記事 Web制作 便利ツール