jQuery – スクロール時にグローバルナビゲーションメニューをページトップに固定

jQuery
この記事は約9分で読めます。
スポンサーリンク

Webページのスクロール時に、ヘッダーナビゲーションメニューをページトップに固定するJavaScriptのご紹介です。
UIデザインの好みやバランスにもよるかと思いますが、私の場合は、ヘッダーメニューはスクロールでページトップ固定もしくは最初からページトップに配置することが多いです。ある統計では、サイドメニューはあまり使われない傾向もあるようなので、常にヘッダーメニューからページ遷移しやすくすることは、アクセシビリティを高めることにも繋がるのではないかと思います。

スポンサーリンク

概要

jQueryによってスクロール位置に応じてClassを追加するスクリプトと、そのClassを含む要素をページトップに配置するCSSで実現します。

実際に作成したデモのHTML、CSS、JS の3つのファイルで説明します。

See the Pen
スクロール時にグローバルナビゲーションメニューをトップに固定
by J. (@umvjcqzk)
on CodePen.

HTML

デモの demo.html の中身です。
headタグ内で demo.css を読み込み、bodyタグ内の最後にjQueryと demo.js を読み込んでいます。
bodyタグ内に、よくあるサブメニューありのナビゲーションメニューを作成しています。

HTML
<!doctype html>
<html lang="ja">
<!-- headタグ部↓ -->
<head>
<meta name="robots" content="noindex">
<link rel="stylesheet" type="text/css" href="demo.css">
</head>
<!-- headタグ部↑ -->
<body>
<div class="header">
<!-- ヘッダー部↓ -->
<div class="header-in">
<h1>Header</h1>
</div>
<!-- ヘッダー部↑ -->
<!-- ナビゲーションメニュー部↓ -->
<nav id="navi">
  <div class="navi-in">
    <ul>
    <li><a href="#">MENU1</a></li>
    <li><a href="#">MENU2</a>
      <ul class="sub-menu">
      <li><a href="#">SUBMENU1</a></li>
      <li><a href="#">SUBMENU2</a></li>
      <li><a href="#">SUBMENU3</a></li>
      </ul>
    </li>
    <li><a href="#">MENU3</a></li>
    </ul>
  </div>
</nav>
<!-- ナビゲーションメニュー部↑ -->
</div>
<!-- コンテンツ部↓ -->
<div class="content">
<h2>Content</h2>
</div>
<!-- コンテンツ部↑ -->
<!-- スクリプト読み込み部↓ -->
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=1.12.4'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/1.4.1/jquery-migrate.min.js?ver=1.4.1'></script>
<script src='demo.js'></script>
<!-- スクリプト読み込み部↑ -->
</body>
</html>

CSS

デモの demo.css の中身です。前半はナビゲーションメニューの固定とは関係ないですが、ブラウザごとの表示の差異を解消するためのCSSのリセットです。
記述をグローバルメニューとヘッダーとコンテンツに分けていますが、ここでの要点はヘッダーのセレクタが #navi.fixed のコードです。

CSS
@charset "UTF-8";
/* CSS RESET
   http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/****** グローバルメニュー ******/
#navi {
background-color: #444;
border-radius: 10px;
width: 80vw;
margin: auto;
}
.navi-in a {
text-decoration: none;
color: #fff;
display: block;
}
.navi-in > ul {
padding: 0;
margin: 0;
list-style: none;
display: flex;
flex-wrap: wrap;
justify-content: center;
text-align: center;
}
/*** サブメニュー ***/
.navi-in > ul li {
display: block;
width: auto;
height: 60px;
line-height: 60px;
position: relative;
margin: 0 12px;
}
.navi-in > ul li:hover > ul {
display: block;
}
.navi-in > ul .sub-menu {
display: none;
position: absolute;
margin: 0;
min-width: 200px;
list-style: none;
padding: 0;
background-color: #ccc;
z-index: 99;
text-align: left;
}
/*** サブメニューのサブメニュー ***/
.navi-in > ul .sub-menu li:hover a {
text-indent: 10px;
}
/****** ヘッダー ******/
#navi.fixed {
position: fixed; /*** ここが要点 ***/
top: 0; /*** ここが要点 ***/
z-index: 100;
width: 100%;
border-radius: 0;
}
.header {
background-color: #ddd;
}
.header-in {
height: 300px;
position: relative;
}
.header-in h1 {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
font-size: 300%;
}
/****** コンテンツ ******/
.content {
height: 1000px;
position: relative;
}
.content h2 {
text-align: center;
margin-top: 1em;
font-size: 200%;
}

JS

demo.js には下記のコードが書かれています。

jQuery
//スクロール時にヘッダーナビをページトップに固定するためのclassを付加
var nav = jQuery('#navi'), //変数の宣言(ヘッダーナビ)
offset = nav.offset().top; // ドキュメントのトップを起点としたヘッダーナビの位置(Y座標)を取得
jQuery(window).scroll(function () { //スクロール時に引数のfunctionを実行
	var scroll = $(this).scrollTop(); //要素のスクロール位置(Y座標)を取得
	if( scroll >= offset) { //スクロール位置の値がヘッダーナビの位置の値以上になった時に
		nav.addClass('fixed'); //ヘッダーナビにClass(fixed)を追加
	} else { //それ以外(スクロール位置の値がヘッダーナビの位置の値未満)は
		nav.removeClass('fixed'); //ヘッダーナビからClass(fixed)を削除
	}
});

以上、ご参考になれば幸いです。

jQueryCSS
スポンサーリンク
スポンサーリンク
J.をフォローする
スポンサーリンク
アトリエJ.

コメント

タイトルとURLをコピーしました