

そんな疑問にお答えします。
はじめはスクロールしているのに、画面上部までいくと固定されるヘッダーを見たことはありませんか?
今回はこのヘッダーの実装方法を紹介します。
目次
スクロール途中からヘッダー固定にする方法
スクロール途中からヘッダー固定にするためのポイント
コードを解説する前にまずどのような仕組みで「スクロール途中からヘッダー固定」にするのかを理解しましょう。
そのためには
- offset().top
- scrollTop()
を理解しておく必要があります。
offset().topとは
jQueryで要素の位置を取得したり移動させるには「offset()」を使います。
offset()ではドキュメントの左上の起点と指定要素の左上の起点の距離を取得します。
取得できる距離は上からの距離と左からの距離の2つです。
下からや右からの距離は取得できません。
scrollTop()とは
scrollTop()は画面をスクロールしたときのスクロール量を取得することができます。
要は「どのくらいスクロールされたか」というのがわかります。
- offset().top → HTML要素の位置を取得
- scrollTop() → スクロール量を取得
ここまで理解できればjQueryでどう制御すればいいのかがわかります。
つまり以下のとおりです。
①特定のHTMLの要素(今回はヘッダー)のoffset().topを取得する
②スクロール量を取得する
③ ②スクロール量が①offset().topを超えた場合ヘッダーを固定、超えない場合は固定しない
それではこれをコードに落とし込みます。
HTML
<body>
<div class="fv"></div>
<header id="js-header" class="header"> <!-- idを設定 -->
<nav class="header-nav">
<ul class="header-nav-list">
<li class="header-nav-item">
<a class="header-nav-item-link" href="#">メニュー1</a>
</li>
<li class="header-nav-item">
<a class="header-nav-item-link" href="#">メニュー2</a>
</li>
<li class="header-nav-item">
<a class="header-nav-item-link" href="#">メニュー3</a>
</li>
</ul>
</nav>
</header>
<section class="container">コンテンツ1</section>
</body>
ここではヘッダーに「id=”js-header”」とつけています。
jQueryで操作するのでclassとは別にidをふっています。
CSS
a {
text-decoration: none;
}
ul {
list-style: none;
}
.fv {
background: url(画像パス) no-repeat center center / cover;
height: 500px;
}
.header {
background: #00CC99;
width: 100%;
}
/* 上部に固定させるスタイルを用意 */
.fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
}
.header-nav-list {
display: flex;
justify-content: space-around;
}
.header-nav-item-link {
display: block;
color: #333;
height: 80px;
line-height: 80px;
}
.container {
height: 1000px;
background: pink;
text-align: center;
font-size: 36px;
padding-top: 60px;
}
ポイントは「.fixed」の設定です。
これはのちほどjQueryで「ヘッダーが画面上部に達したら.fixedを付与する」という処理を行います。
その場合の上部に固定させるというスタイルを記述しています。
jQuery
$(function () {
// ヘッダーの位置
const pos = $('#js-header').offset().top;
// ヘッダーの高さ
const height = $('#js-header').outerHeight();
$(window).scroll(function () {
// スクロール量がヘッダーの位置を超えた場合
if ($(this).scrollTop() > pos) {
// ヘッダーにfixedクラスを付与
$('#js-header').addClass('fixed');
// bodyにヘッダーの高さ分のpadding-topをつける
$( 'body' ).css( 'padding-top', height);
// 超えない場合
} else {
//ヘッダーのfixedクラスを外す
$('#js-header').removeClass('fixed');
// bodyのpadding-topをなくす
$( 'body' ).css( 'padding-top', 0);
}
});
});
今までのところで解説してきたことをjQueryに記述します。
やりたいことは「ヘッダーの位置」と「スクロール量」を比較して「fixedクラス」をつけ外しする、ということです。
(補足)
const height = $('#js-header').outerHeight();
$( 'body' ).css( 'padding-top', height);
これは何をしているのかというと、まず上の行でヘッダーの高さを取得しています。
そして下の行で、「bodyにヘッダーの高さ分のpadding-top」を指定しています。
これがないとコンテンツが一部ヘッダーに隠れてしまいます。
それを防ぐための記述です。
一見、jQueryの記述が長くて理解するのが大変そうですが、各パートごとに見ていくと何をしているのかが徐々にわかってくると思います。
一度自分で実装してみれば難しそうと感じるハードルも下がるはずです。
ぜひ試してみてください。
投稿者 トシ
コメントを残す