・ページ内リンクのジャンプ先が、固定ヘッダーと重なってしまう…。
・レスポンスシブで、固定ヘッダーの高さが変わるけど、対応できるかな?
・スマートフォンのときだけ、固定ヘッダーなんだけど、条件分岐はどうやるの?
という悩みを解決できる記事を書きました。
【この記事の信頼性】
当ブログ(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も含み)