固定ヘッダー時に、ページ内リンクがずれるときの解決方法【レスポンスシブ対応】

・ページ内リンクのジャンプ先が、固定ヘッダーと重なってしまう…。
・レスポンスシブで、固定ヘッダーの高さが変わるけど、対応できるかな?
・スマートフォンのときだけ、固定ヘッダーなんだけど、条件分岐はどうやるの?

という悩みを解決できる記事を書きました。

【この記事の信頼性】
当ブログ(RENBLOG)の編集長である僕は、これまでホームページ制作に約40サイト以上、携わらせて頂いております。

また、当ブログ(RENBLOG)は、記事数は少ないですが、数ページほど、10以内を獲得している為、割と信頼できるのではと思います。

ページ内リンクの位置ずれの解決方法【レスポンスシブ対応】

jQueryに記述するためのコードです。
コピペしてお使いください。

$(function(){

  let headerHeight = $('#header').outerHeight();
  let speed = 600;

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

});


ポイント

let headerHeight = $('#header').outerHeight();

ヘッダーの高さを、(例: let headerHeight = 80) というように、固定値で設定せずに、
$('#header').outerHeight(); で、自動的に固定ヘッダーの高さを取得しているため、


レスポンシブで、固定ヘッダーの高さが変わっても、柔軟に対応できるようにしております。


style.cssの修正が入ったときに、jQuery側も修正となると、僕は発狂します。

解説コード

$(function(){

  // ヘッダーの高さを取得して、headerHeight(変数)に代入しています

  // $('〇〇')の中は、自分のブログやサイトのコードに合わせて、書き換え
  // (例: $('.l-header'), $('.header'))

  // outerHeight()は、要素のpaddingとborderを含めた高さを取得する方法
  // 他には、height(),innerHeight(),outerHeight(true)がある
  // ヘッダーが固定値(例: height: 100px;)の場合は、height()で問題なし
  // 基本的に、要素の高さを固定値にしないため、outerHeight()を使用
  let headerHeight = $('#header').outerHeight();

  // speed(変数)に、スクロール速度(0.6秒)を代入しています
  // 管理がしやすいという理由で、変数に代入する方法が、推奨されています
  // 対象のジャンプ先まで、0.6秒かけてスルスルと移動します
  // 600が平均的かと。ランディングページ(LP)のように、縦に長くスクロール量が多い場合は、500を使用したりします
  let speed = 600;

  // #で始まるアンカーリンク(ページ内リンク)をクリックした時に処理する
  // ^= とは、ビット排他的論理和演算子という、jQueryの構文の一つです。深く気にする必要はないかと。
  $('a[href^="#"]').click(function() {

    // クリックしたaタグの値を取得して、href(変数)に代入しています
    // このあたりから、頭が痛くなる方は、サラーっと流してください
    let href= $(this).attr("href");

    // ジャンプ(アンカーリンク)先のURLの値が、#か空白だったら'html'を、それ以外だったら先ほど取得した、href(変数)をtarget(変数)に代入
    // #か空白だったら'html'を... = ページトップへ、スクロールする
    let target = $(href == "#" || href == "" ? "html" : href);

    // target.offset().topで、ページトップからジャンプ(スクロール)先までの距離を取得
    // このままだと固定ヘッダー分ずれるため、- headerHeight で、最初に取得したヘッダーの高さを引いて戻す
    let position = target.offset().top - headerHeight;

    // ジャンプ(アンカーリンク)先まで、speed(0.6秒)かけて、スルスルとスクロールします
    // "swing"  = 始めはゆっくり動いて、途中はちょっと速め、最後はゆっくりと動く
    // "linear" = 常に同じ速さで動く
    $('html, body').stop().animate({scrollTop:position}, speed, "swing");

    // return false; = URLにアンカーリンクが表示されるのを防ぐ
    // return false; を書かなければ、URLにアンカーリンクが表示される
    // (例: https://renkosaka.com/#anchor-link)
    // 最後の一行を書かなくても動きますので、自分の好みかなと
    return false;
  });

});

height(),innerHeight(),outerHeight(true)の違いが分かる、参考記事

jQueryで高さの取得と設定(height,innerHeight,outerHeight)

【応用編】固定ヘッダーが、スマホの時だけの条件分岐

直近で受けた案件が、スマホの時だけ、固定ヘッダーかつ、ページ内リンクがありましたので、備忘録も含めて書いております。

$(function(){

  // ブラウザの横幅(画面幅)が428px(スマホ時のブレークポイントは、ディレクターの指示に従う)以下の時の処理
  if(window.matchMedia("(max-width: 428px)").matches) { // ここから

    let headerHeight = $('#header').outerHeight();
    let speed = 600;

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

  } // ここまで

});

ポイント

if(window.matchMedia("(max-width: 〇〇px)").matches) {

}

jQueryではブラウザの横幅(画面幅)によって処理を変えることができますので、
上記の条件分岐のコードを使って、〇〇pxまでは、固定ヘッダー分だけずらしております。
〇〇pxは、任意の数字)



max-width: 767px; = 767px以下(767pxも含む)

min-width: 768px = 768px以上(768pxも含み)

SNSでもご購読できます。

コメントを残す

前の記事

次の記事