スクロール後にヘッダー固定するグロナビメニューの作り方【jQuery】

Programming

今回の記事では、jQueryを使って画面を少しスクロールしたらヘッダーに固定されるグローバルナビケーションメニューの作成の仕方を紹介します。(コピペOK)

jQueryを使ってヘッダー固定をすると、スクロールした時にカクっとズレが応じる事があります。その対処法も一緒に説明します。更にアンカーリンクをクリックした後に滑らかにスクロールする「スムーススクロール」の実装方法も紹介します。もし悩んでいるのでしたら参考にして下さい。

グロナビメニューの作り方

まずはグロナビメニューの作り方を解説します。グロナビはHTMLとCSSだけで作成できます。

HTML

HTMLはnav要素ul要素を使って以下の様にコーディングします。テキストはspan要素で囲んだ方が後からデザインを変えやすいいです。

<header>
<nav class="gnavi">
        <div class="gnavi_inner">
          <ul>
            <li><a href="#"><span>TOP</span></a></li>
            <li><a href="#menu01"><span>menu01</span></a></li>
            <li><a href="#menu02"><span>menu02</span></a></li>
            <li><a href="#menu03"><span>menu03</span></a></li>
          </ul>
        </div>
      </nav>
</header>

CSS

CSSではgnaviクラスに効いているposition: absolutetop:0width: 100%が基本の位置を作成してます。gnavi_innerwidth: 980pxと幅を決めていますのでスマホ対応時に注意が必要です。gnavi ulgnavi lignavi aで効いてるdisplay: flexが横に綺麗に並んだレイアウトを可能にしています。

あとはデザインのためのスタイルなのでお好みで編集して下さい。

.gnavi {
  height: 80px;
  background-color: rgb(232, 226, 207);
  box-shadow: 0 3px 6px -3px #000000 inset;
  position: absolute;
  z-index: 999;
  width: 100%;
  top:0;
}

.gnavi_inner {
  width: 980px;
  height: 100%;
  margin: 0 auto;
}

.gnavi ul {
  height: 100%;
  display: flex;
  margin: 0 -20px;
}

.gnavi li {
  flex: 1 1;
  position: relative;
  display: flex;
}

.gnavi li::after {
  content: "";
  display: block;
  width: 2px;
  height: 20px;
  background-color: #b8b9dc;
  position: absolute;
  right: -1px;
  top: calc((100% - 20px)/2);
}

.gnavi li:last-child::after {
  content: none;
}

.gnavi a {
  display: flex;
  flex: 1 1;
  justify-content: center;
  padding: 0 20px;
  text-decoration: none;
}

.gnavi a:hover span {
  color: #7172ac;
  position: relative;
}

.gnavi a:hover span::after {
  content: "";
  position: absolute;
  display: block;
  height: 4px;
  width: 100%;
  bottom: 0;
  background-color: #7172ac;
  border-radius: 5px;
}

.gnavi span {
  display: flex;
  align-items: center;
  word-break: keep-all;
}

a {
  color: inherit;
  text-decoration: none;
}

 /* – ------- – スマホ時 – ------- – */

@media screen and (max-width:575px) {

  .gnavi__inner {
    width: 100%;
  }
  .gnavi__inner ul {
    margin: 0;
    padding: 0;
  }

  .gnavi a {
    padding: 0;
  }

するこ以下の様な見た目が完成します。これで見た目は完成です。

グロナビをスクロール後にヘッダー固定する

次は、以下のように画面をスクロールした後にグロナビをヘッダーに固定する方法を紹介します。

まずは、CSSに以下の記述を追加します。

.gnavi.fixed{
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  background:rgb(232, 226, 207, 0.8);
}

.gnavi.fixedposition: fixedにする。すなわち固定されると言う事です。しかしHTML上には.gnavi.fixedのクラスは書いていません。そこで以下のJacaScriptコードでDOM操作をして、そのクラスをHTML上に追加します。

common.jsなどの名前でカスタム用jsファイルを作成して、そこに以下のコードを入れて下さい。

$(function() {
	var headNav = $(".gnavi");
	$(window).on('load scroll', function () {
		if($(this).scrollTop() > 100 && headNav.hasClass('fixed') == false) {
			headNav.css({"top": '-100px'});
			headNav.addClass('fixed');
			headNav.animate({"top": 0},600);
		}
		else if($(this).scrollTop() < 100 && headNav.hasClass('fixed') == true){
			headNav.removeClass('fixed');
		}
	});
});

意味は以下です。

.gnaviに対して、windowがlordされたうえでscrollされたら以下が実行されます。
もしTOPから見て100pxスクロールされたら.gnaviクラスに.fixedをを付けて.gnavi.fixedにする。
100pxスクロールされてない状態だったら.gnavi.fixedから.fixedを外す。

これだけで完成です。100px分スクロールしたらグロナビがposition: fixed(固定)になります。

グロナビリンクをスムーススクロールにする

LPで良く見かける仕様で、グロナビリンクをクリックしたときに滑らかにスクロールして、メニュー該当位置で止まる様な仕様を「スムーススクロール」と言います。その方法も一緒に説明します。

まずはhttps://jquery.comからjQueryのデータをダウンロードしてjsファイルに入れて下さい。

もしくは以下のコードをhead内に入れてオンラインから読み込んで下さい。

<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

jQueryを読み込んだらcommon.jsなどの名前で作成したカスタム用jsファイルに以下を記述します。

$(function(){
  $('a[href^="#"]').click(function(){
    var speed = 500;
    var href= $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
    $("html, body").animate({scrollTop:position}, speed, "swing");
    return false;
  });
});

これだけで完成です。

グロナビに記述している「a href="#"」というリンクをクリックしたときに以下が実行されます。
500ミリ秒かけて「a href="#"」で指定しているリンクの場所にスイングのアニメーションを実行。

といった事が処理されています。

着地地点がズレる時の対処法

ここまで紹介した方法でグロナビを作成すると以下の様に着地地点がズレる場合があります。ピッタリ止まらないと若干気持ちが悪いので次の方法で対処しましょう。

グロナビの着地地点がズレる場合は以下のCSSを<section>に対して追加して下さい。(各々のサイトで調整は必要です。)

margin-top: -80px; /* 固定ナビの高さ分のネガティブマージン */
padding-top: 80px; /* 打ち消し用のパディング */ 

考え方は非常に簡単で、着地地点をマージンで無理矢理下にずらしてピッタリ収まる位置に移動させます。そして移動させた分パディングで元の位置に戻します。

こうすることで視覚的な位置は変わっていなくても、内部的には位置が変わったことになるので調整ができると言うわけです。

後ろのコンテンツがカクっとズレる時の対処法

次に、スクロールしてグロナビが固定される瞬間に以下の様にカクッと後ろのコンテンツがズレ込む時の対処方を紹介します。

原因はグロナビが固定される際に、サイト最上部にあったグロナビが消えて画面の上に移動されるからです。この時にサイト最上部にあったグロナビの高さ分コンテンツ全体が上に押し込まれてしまいます。

これを解消するにはグロナビ分の高さを常に確保しとく事です。

結論を言うと、headerにグロナビの高さ分のパディングを付けるだけです。(今回の場合は80pxです。)

header {
  padding-top: 80px;
}

gnaviの高さはheight:80pxで指定している。またposition: absolutetop:0によってheaderpadding-top: 80pxの上に重ねて配置されてます。

.gnavi {
  height: 80px;
  position: absolute;
  top:0;
  }

こうする事でheaderの80pxが常に確保されることになります。すなわちズレが起きなくなります。


以上が「スクロール後にヘッダー固定するグロナビメニューの作り方【jQuery】」でした。また今回紹介した技術は、WEB制作では必ずといって良いほど必要な技術なのでしっかりと覚えましょう。少しでも参考になれば幸いです。

三浦圭人

最後まで閲覧頂きありがとうございます。
Twitterでは更に細かくWEBリテラシーのネタを発信しています。是非フォローお願い致します。感想/ご意見頂けたら喜びます✨

ProgrammingCSS,JavaScript,jQuery

Posted by KT