jQuery

【スティッキーヘッダー】固定、変化、一旦隠れるパターンをjQueryで

 

Webサイト制作で、ほとんどのサイトで見かけるのが「スティッキーヘッダー」です。

stickyって「粘着性」という意味で、その名の通りくっ付いてくるヘッダーのこと。

 

常にメニューが見える場所にあることで、ユーザビリティを高めてくれます。

基本はjQueryとCSSで実装することになりますね。

 

今回は、よくあるパターンをいくつかまとめてみましたので、参考にしてみてください!

 

スティッキーヘッダーのよくあるパターン3選

 

よく見かけるデザインとしては、こんな感じかなーと思います。

  • そのまま追従
  • デザインが変わる
  • 一旦隠れて途中から出現

 

スクロールで粘着質に追従

 

jQueryでスクロールを監視して、ナビゲーションメニューの高さ分スクロールしたらクラスを付与しているだけですね。

headerやnavには特殊なクラス名をつけていないので、HTMLコードの紹介は省きます。

本来は、それぞれにクラスをつけて管理するのが望ましいです。

 

CSS

.is-fixed {
 position: fixed;
 top: 0;
 left: 0;
 z-index: 2;
 width: 100%;
}

 

 

jQuery

$(function() {
  var $win = $(window),
      $main = $('main'),
      $nav = $('nav'),
      navHeight = $nav.outerHeight(),
      navPos = $nav.offset().top,
      fixedClass = 'is-fixed';

  $win.on('load scroll', function() {
    var value = $(this).scrollTop();
    if ( value > navPos ) {
      $nav.addClass(fixedClass);
      $main.css('margin-top', navHeight);
    } else {
      $nav.removeClass(fixedClass);
      $main.css('margin-top', '0');
    }
  });
});

 

スティッキーヘッダの実装は、「jQueryのスクロール監視」がポイントになってきます!

 

長くなりますが、一つずつ解説していきます!

変数宣言

  var $win = $(window),
      $main = $('main'),
      $nav = $('nav'),
      navHeight = $nav.outerHeight(),
      navPos = $nav.offset().top,
      fixedClass = 'is-fixed';

 

このステートメントでは、それぞれの変数宣言とバインド(初期値の割当)してます。

変数に入れた値はいつでも変更できるので、管理がしやすくなります。

 

mainやnav、is-fixedのクラス名のバインド部分はなんとなく分かりますね?

単純に変数を宣言して、指定したタグやクラスを代入しています。

 

var $win = $(window),

「ページ全体が読み込まれた後に実行してね」という処理のために宣言しています。

 

navHeight = $nav.outerHeight(),

「要素の高さを求めるメソッド」で、この値はパディングやボーダーの値も含めます。

 

navPos = $nav.offset().top,

offsetメソッドは、「jQueryの要素の距離の値を取得するメソッド」です。

2つのプロパティがあり、topは上端からの距離、leftは左端からの距離です。

つまりここでは、<nav>の上端からの距離を初期値として変数に格納していますね。

 

これらを予め変数としてバインドしておくことで、jQueryの記述が楽になります。

 

  • ステートメントは「式」
  • バインドは「代入」

という意味です!かっこいいので使いたいだけです!

 

スクロールイベントを監視して処理する

  $win.on('load scroll', function() {
    var value = $(this).scrollTop();
    if ( value > navPos ) {
      $nav.addClass(fixedClass);
      $main.css('margin-top', navHeight);
    } else {
      $nav.removeClass(fixedClass);
      $main.css('margin-top', '0');
    }
  });

 

 

$win.on('load scroll', function() {

「ウィンドウが読み込まれた時、スクロールイベントが発生した時に実行してね!」という意味。

その中に、スクロール監視してどんな処理をするのかを書いていきます。

 

var value = $(this).scrollTop();

scrollTop();は、「縦方向にどれだけスクロールされたかを調べるメソッド」です。

つまり、ウィンドウがどれだけスクロールされたかを調べ、スクロール量を変数valueにバインドしています。

 

    if ( value > navPos ) {
      $nav.addClass(fixedClass);
      $main.css('margin-top', navHeight);
    } else {
      $nav.removeClass(fixedClass);
      $main.css('margin-top', '0');
    }

 

valueとnavPosを比較して条件分岐していますが、日本語に変換するとこうなります。

 

もし(ウィンドウのスクロール量が<nav>の初期位置よりスクロールされたら)

<nav>にis-fixedというクラスをつける

<main>に<nav>と同じ高さ分のmargin-topをつける

 

そうじゃない場合は・・

 

<nav>からis-fixedというクラスを削除する

<main>のmargin-topを0にする

 

 

offset().top,scrollTop()の意味がわかれば簡単ですよね。

あとはCSSでクラスをつけたり外したりするだけで結構簡単にできてしまいます。

 

実は
CSSだけでもできるらしく、詳しくはコリスさんの記事を参考にしてみて下さい。

 

これを応用すれば、他にもいろんなパターンのスティッキーヘッダーが実装できるので、ご紹介します。

スクロールでヘッダーのデザインが変わる

 

header {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
  width: 100%;
  height: 120px;
  padding:20px;
  text-align: center;
  background-color: #EAB543;
  transition: .3s;
}
header h1 {
  color: #333;
  transition: .3s;
}
.is-fixed {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
  width: 100%;
}

.is-animation {
  background-color: rgba(0, 0, 0, 0.7);
  height: 90px;
  padding:5px;
}
.is-animation h1 {
  color: #fff;
}
.is-animation nav ul li a {
  color: #fff;
}

 

$(function() {
      var $win = $(window),
          $header = $('header'),
          animationClass = 'is-animation';
      $win.on('load scroll', function() {

        var value = $(this).scrollTop();
        if ( value > 100 ) {
          $header.addClass(animationClass);
        } else {
          $header.removeClass(animationClass);
        }
      });
    });

 

これもよくあるパターンですね!

基本的には①と変わらず、クラスの付け替えで操作しています。

今回は色を変えてますが、ヘッダーの高さが変わるのもよく見ますし、実装する機会も多いです。

 

スクロールで一旦隠れて、途中からひょっこり出てくる

.clone-nav {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 2;
    width: 100%;
    transition: .3s;
    transform: translateY(-100%);
  }

  .is-show {
    transform: translateY(0);
  }

 

$(function() {
    var $win = $(window),
        $cloneNav = $('nav').clone().addClass('clone-nav').appendTo('body'),
        showClass = 'is-show';
  
    $win.on('load scroll', function() {
      var value = $(this).scrollTop();
      if ( value > 700 ) {
        $cloneNav.addClass(showClass);
      } else {
        $cloneNav.removeClass(showClass);
      }
    });
  });

 

ちょっとややこしくなってきました。。

jQueryのclone()メソッドを使って、body内にナビゲーションを複製し、それを改めて表示させています。

 

まとめ

コピペだけじゃなくて、少しずつ理解を深めていくのは重要です。

特に、jQueryはコピペでも実装できるので、簡単に済ませてしまいがちですが、何かエラーが起きた時とか、カスタマイズしたい時に対応が難しくなります。

 

一つずつメソッドを理解しつつ、こういったよくあるUIで練習していくのがいいかもしれませんね!