今回はヘッダーにposition: fixed
を指定している場合に別ページからアンカーリンクに遷移するとヘッダーの高さ分ずれてしまうアレの対処法を解説します。
別ページへのアンカーリンクがヘッダーの高さ分ずれる時の対処法
早速結論ですが、以下のコードをコピペでokです!jQueryは先に読み込んでおいてくださいね。
$(window).on('load', function() {
let headerHeight = $('.l-header').outerHeight();
let urlHash = location.hash;
if (urlHash) {
let position = $(urlHash).offset().top - headerHeight;
$('html, body').animate({ scrollTop: position }, 0);
}
});
ざっくり解説します。
まず$(window).on('load')
で読み込むのが結構大事です($(function() {})
にはしない)。コンテンツ量が多かったり読み込み速度が遅いとページ遷移後にアンカーリンクがずれてしまう可能性があるので、ロードが完了してから処理をします。
またouterHeight()
でヘッダーの高さを取得、location.hash
でurlの「#」以降のハッシュの部分を取得します。
あとはそのハッシュ(id)を持つ要素の位置をoffset().top
で取得し、ヘッダーの高さ分逆方向に戻せばokです。
注意点として、上のコードにあるurlHash
と$(urlHash)
は全然違うので気をつけてくださいね。
urlHash
は「#」以降の部分なのでそのまま「#contents01」みたいな感じでidそのものを取得できますが、$(urlHash)
はjQueryオブジェクトなのでそのidを持つ「要素」が取得されます。
$(urlHash).offset().top
としているのはidそのものではなく要素じゃないと位置を取得できないからですね。
CSSだけでもできる
ちなみにjQueryを使わなくてもCSSだけでも出来ちゃいます。
コードはこんな感じ。数値の部分にはヘッダーの高さを入れます。
#contents01 {
/* ヘッダーの高さ分を指定 */
padding-top: 100px;
margin-top: -100px;
}
marginで開けた余白はoffset().top
で要素の位置を取得する上ではカウントされませんが、paddingで開けた余白は要素の高さとして認識されます。なので単純にヘッダーの高さ分のpaddingを開ければヘッダーと被らなくなります。
ただ、それだけだと余白が空きすぎてしまうのでmarginに同じ値をマイナスで指定してプラマイゼロになるようにしています。
CSSだけでもできてしまうのはすごいですが、直感的にわかりにくい気がするので個人的にはjQueryを使うほうが好きですね。
まとめ
ページ外からアンカーリンク付きのページに移動するとどうしてもヘッダーの高さ分ずれてしまいますが、jQueryを使ったりCSSを一工夫することでいい感じにできます。
コードも簡潔でそれなりに使うことも多いと思うので使ってみると綺麗にページ移動ができますね。