以下のように画面をスクロールすると、ヘッダーがフワッと表示されて追従(トップに固定)するヘッダーの作り方を紹介します。(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';
}
}
- スクロールダウン時:
scrollTop
がlastScrollTop
より大きい場合- このとき、
scrollTop
がmainHeader.clientHeight
(ヘッダーid="main-header"
のY軸方向の位置)を超えている場合(つまりヘッダーが見えなくなったとき)、fixedHeader
を表示します。
- このとき、
- スクロールアップ時:
scrollTop
がlastScrollTop
より小さい場合- このとき、
scrollTop
がmainHeader.clientHeight
(ヘッダーid="main-header"
のY軸方向の位置)以下に戻った場合(つまりヘッダーが表示されたとき)、fixedHeader
を非表示にします。
- このとき、
最後に、現在のスクロール位置を lastScrollTop
に保存して、次回のスクロールイベントで比較できるようにします。
lastScrollTop = scrollTop;
(おまけ)PCとモバイルでメニュー表示を変える
本筋とは関係ないですが、ウィンドウ幅に応じてメニュー表示を変更するにはメディアクエリを利用します。
(実装例では、ウィンドウ幅が広い時にナビメニュー、ウィンドウ幅が狭い時にハンバーガーメニューを表示しています。)
この辺りも合わせて実装できれば、よりヘッダーらしくなりますね。
メディアクエリとハンバーガーメニューについてはそれぞれ別記事で紹介していますので、合わせてご覧ください。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。