【jQuery】スクロールでデザインがコンパクトに変化するスティッキーヘッダーの作り方

key-visual JavaScript

「スティッキーヘッダーを作ったけど大きすぎて邪魔だな…途中でコンパクトに変わるようにしたいな」。

そんな時のために、今回はjQueryを使ってスクロールするとヘッダーがコンパクトに変化するスティッキーヘッダーの作り方を紹介します。

 

今回は通常のヘッダーがスクロールによって画面外に出たらコンパクトなスティッキーヘッダーを上からスッと出すようにします。

 

スポンサーリンク

デモページ

今回作るスティッキーヘッダーのデモを用意しました。以下のリンクから動作確認をして見てください。

>>デモページ

 

スクロールで変化するスティッキーヘッダーの作り方

HTML

ヘッダー部分のHTMLはこんな感じです。

<header class="header">
  <p>ヘッダーです</p>
</header>

<header>タグでヘッダーを作っただけですね。

HTMLはこれだけでokです。

 

CSS

CSSはこんな感じ。

/* headerを囲む要素にposition: relative; */
body {
  position: relative;
}
.header {
  width: 100%;
  height: 100px;
  background-color: pink;
  position: absolute;/* レイアウトに影響を与えないようにabsoluteにしておく */
  top: -100px;/* 配置調整(重要!) */
  margin-top: 100px;/* 配置調整(重要!) */
  transition: top 300ms;/*  ここのtransitionでtopだけを指定する(重要!)  */
}
/* スティッキー時に.stickyクラスを追加 */
.header.sticky {
  position: fixed;/* 上に固定 */
  top: 0;/* 上からスッと表示させる(重要!) */
  margin-top: 0;/* 0にすることでtopで上に配置 */
  height: 50px;/* 小さく変化させる */
}

bodyposition: relative;を指定していますが、別にbodyじゃなくても構いません。headerposition: absolute;を指定したいので、要はheaderを囲む要素にposition: relative;を指定すればokです。囲むタグは<div>とかでも大丈夫です。

headerは最初からposition: absolute;で配置します。スティッキー時にposition: fixed;にしますが、いきなりそうしちゃうと他のレイアウトに影響が出てしまうためそれを防ぐ用です。

 

上からスッと表示させる上で大事なのがtop: -100px;margin-top: 100px;です。詳しくは後述しますが、現時点では相殺されて位置はプラマイゼロという認識でokです。

もう一つ大事なのが、transition: top 300ms;です。transitionの対象はtopだけということに注意しましょう。

 

スティッキー時にはjQueryで.stickyクラスを入れます。position: fixed;を入れて上部に固定します。

ここからが一番大事な部分です。

.stickyクラスが入った時にtopmargin-top0にします。

margin-topはすぐに0に変わりますが、top: -100px;transition: top 300msにある通り300msかけてアニメーションします。margin-top: 0;になった瞬間ヘッダーはまだtop: -100px;の位置にあり、そこから300msかけてtop: 0になるので上からスッと出てくるというわけです。

よくわからない人はこの辺の数字を適当にいじってみるとなんとなくわかってくると思います。

 

最後にスティッキー時にはヘッダーをコンパクトに変化させたいので、height: 50px;で高さを低くします。こうすれば大きいヘッダーもさほど邪魔じゃなくなりますね。

 

jQuery

$(function () {
  $(window).on('load scroll', function () {
    var $header = $('.header');

    // 200以上スクロールしたら処理
    if ($(window).scrollTop() > 200) {
      $header.addClass('sticky');
    } else {
      $header.removeClass('sticky');
    }
  });
});

jQueryはロード時とスクロール時に処理をします。スクロール時だけだとスクロールをしない限りイベントが発生しないという状態になってしまいます。ページの途中でリロードしてもすぐにヘッダーが表示されるように、ロード時にもイベントが発火するようにしておくといいですね。

$(window).scrollTop()で上からのスクロール量を取得します。scrollTop()は名前通りトップからのスクロール量を取得するメソッドです。$(window)に対して処理をかけるとページの一番上からのスクロール量が取得できます。

処理自体は単純で、200以上スクロールしたらstickyクラスを入れる、それ以外なら外すというだけです。クラスの付け外しでヘッダーを普通のものかスティッキー状態かを変化させているわけですね。

もちろん200の数字を変更すればスティッキーヘッダーが表示される場所を好きな場所にできます。

 

★参考書籍

 

CSSだけでスティッキーヘッダーを作る方法もある!

シンプルなスティッキーヘッダーなら実はCSSだけで実装することもできちゃいます!

以下の記事でやり方を解説しているので興味のある人はチェックして見てください!

>>【jQuery不要】CSSだけ!途中から追従するスティッキーヘッダーを簡単に作る方法(サンプル付)

 

まとめ

スティッキーヘッダーは何パターンか種類がありますが、処理自体はシンプルなものが多いです。

使う頻度も結構高いので理解しておくとスキルアップにつながるはずです。