【jQuery】ページ内リンクでスムーズスクロール(固定ヘッダーがあったら)

デザオ
するする動くと楽しいですねー
デザコト
固定ヘッダーがある場合はクラスやIDを指定して高さ調整しましょうー

JavaScript

固定のヘッダー(ナビ)がある場合はヘッダー分の高さを調整しなければなりません。レスポンシブだと高さが変わってしまいます。そんな時には『ヘッダー』のクラスやIDを指定してあげれば面倒な調整は不要になります。ちなみに今回の『ヘッダー』は『header』を使っています。

▽jQuery(必須)

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

▽簡単な説明を記載しています。

$(function(){
  var headerHeight = $('header').outerHeight(); // ヘッダーについているID、クラス名など、余白を開けたい場合は + 10を追記する。
  var urlHash = location.hash; // ハッシュ値があればページ内スクロール
  if(urlHash) { // 外部リンクからのクリック時
    $('body,html').stop().scrollTop(0); // スクロールを0に戻す
    setTimeout(function(){ // ロード時の処理を待ち、時間差でスクロール実行
      var target = $(urlHash);
      var position = target.offset().top - headerHeight;
      $('body,html').stop().animate({scrollTop:position}, 500); // スクロール速度ミリ秒
    }, 100);
  }
  $('a[href^="#"]').on('click', function(){ // 通常のクリック時
    var href= $(this).attr("href"); // ページ内リンク先を取得
    var target = $(href);
    var position = target.offset().top - headerHeight;
    $('body,html').stop().animate({scrollTop:position}, 500); // スクロール速度ミリ秒
    return false; // #付与なし、付与したい場合は、true
  });
});

▽JavaScriptには以下の記述でオッケーです。

$(function(){
  var headerHeight = $('header').outerHeight();
  var urlHash = location.hash;
  if(urlHash) {
    $('body,html').stop().scrollTop(0);
    setTimeout(function(){
      var target = $(urlHash);
      var position = target.offset().top - headerHeight;
      $('body,html').stop().animate({scrollTop:position}, 500);
    }, 100);
  }
  $('a[href^="#"]').on('click', function(){
    var href= $(this).attr("href");
    var target = $(href);
    var position = target.offset().top - headerHeight;
    $('body,html').stop().animate({scrollTop:position}, 500);
    return false;
  });
});

【実装】ページ内リンクのスクロール(固定ヘッダーがあったら)

コードを見る(HTML・CSS・jQuery)

HTML

<header>
  <h1>固定ヘッダーがあっても、ぴったり止まる</h1>
</header>

<section>
  <div class="inner">

    <ul class="list" id="m_01">
      <li><a href="#a_1">1</a></li>
      <li><a href="#a_2">2</a></li>
      <li><a href="#a_3">3</a></li>
      <li><a href="#a_4">4</a></li>
      <li><a href="#a_5">5</a></li>
      <li><a href="#a_6">6</a></li>
    </ul>

    <div class="oneArea" id="a_1">
      <div class="one_title">1</div>
      <a class="button" href="#m_01">▲ メニューに戻る</a>
    </div>

    <div class="oneArea" id="a_2">
      <div class="one_title">2</div>
      <a class="button" href="#m_01">▲ メニューに戻る</a>
    </div>

    <div class="oneArea" id="a_3">
      <div class="one_title">3</div>
      <a class="button" href="#m_01">▲ メニューに戻る</a>
    </div>

    <div class="oneArea" id="a_4">
      <div class="one_title">4</div>
      <a class="button" href="#m_01">▲ メニューに戻る</a>
    </div>

    <div class="oneArea" id="a_5">
      <div class="one_title">5</div>
      <a class="button" href="#m_01">▲ メニューに戻る</a>
    </div>

    <div class="oneArea" id="a_6">
      <div class="one_title">6</div>
      <a class="button" href="#m_01">▲ メニューに戻る</a>
    </div>

  </div>
</section>

CSS

/*==============
固定ヘッダー
==============*/

header {
  position: sticky;
  top: 0;
  z-index: 1;
}
header h1 {
  font-size: 22px;
  line-height: 2.0;
  padding: 1em .5em;
  margin: 3em 0 0;
  text-align: center;
  background: #e8dc6a;
}

/*==============
ページ内リンク
==============*/

section {
  background: #f3efe6;
  padding: 120px 20px;
}
section .inner {
  max-width: 1024px;
  margin: 0 auto;
}
section .oneArea {
  margin-bottom: 200px;
}
section ul.list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  list-style-type: none;
  margin: 0 0 100px;
  padding: 0;
  box-sizing: border-box;
}
section ul.list li {
  width: calc(100% / 6);
  text-align: center;
}
section ul.list li a {
  display: block;
  padding: 10px;
  text-decoration: none;
  color: #fff;
  background: #2b2a27;
  border-right: 1px solid #fff;
  transition: .3s;
}
section ul.list li:last-child a {
  border-right: none;
}
section ul.list li a:hover {
  color: #2b2a27;
  background: #fff;
}
section .oneArea .one_title {
  color: #fff;
  text-align: center;
  padding: 10px;
  background: #2b2a27;
}
section .oneArea a.button {
  display: block;
  font-size: 12px;
  color: #2b2a27;
  text-align: center;
  background: #fff;
  border: 1px solid #e8e3d8;
  padding: 10px;
  text-decoration: none;
  transition: .3s;
  margin-top: 40px;
}
section .oneArea a.button:hover {
  background: #e8dc6a;
}

/* 動きを減らす設定のとき(jQuery の動きは <script> の $.fx.off で止める) */
@media (prefers-reduced-motion: reduce) {
  section ul.list li a,
  section .oneArea a.button { transition: none; }
}

jQuery

// ページ内リンク
$(function(){
  // 動きを減らす設定のときは、jQuery の動きを止める
  $.fx.off = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  var headerHeight = $('header').outerHeight(); // ヘッダーについているID、クラス名など、余白を開けたい場合は + 10を追記する。
  var urlHash = location.hash; // ハッシュ値があればページ内スクロール
  if(urlHash) { // 外部リンクからのクリック時
    $('body,html').stop().scrollTop(0); // スクロールを0に戻す
    setTimeout(function(){ // ロード時の処理を待ち、時間差でスクロール実行
      var target = $(urlHash);
      var position = target.offset().top - headerHeight;
      $('body,html').stop().animate({scrollTop:position}, 500); // スクロール速度ミリ秒
    }, 100);
  }
  $('a[href^="#"]').on('click', function(){ // 通常のクリック時
    var href= $(this).attr("href"); // ページ内リンク先を取得
    var target = $(href);
    var position = target.offset().top - headerHeight;
    $('body,html').stop().animate({scrollTop:position}, 500); // スクロール速度ミリ秒
    return false; // #付与なし、付与したい場合は、true
  });
});

外部リンクからのスクロールでもズレません

外部ページのリンクからでも固定ヘッダーの高さを調整しておきましょう。

メモ

jQueryのことで何かわからないことがあればjQueryの日本語リファレンスサイトがあるので一度チェックしてみるといろいろ解決できたりしますよ。

さいごに

デザオ
スクロール楽しいですねー
デザコト
固定ヘッダーがあってもぴったりですー

ふたりの小言

関連記事

デザコトauthor

あ、いいな、と思うWebデザインを紹介しています。デザインの参考に。やさしいデザインが多いです。Webデザインギャラリー『デザインのこと - Web design gallery』を運営しています。