ヘッダー部分を「position:fixed;」で固定してスクロールに追尾させていると、アンカーリンク(ページ内リンク)への移動時に、固定したヘッダー部分の高さ分、移動先の位置がずれてしまいます。
正確には、位置がずれるというか、固定ヘッダーが移動先の要素の上に被ってしまい、位置がずれているように感じます。いずれにしても厄介な問題です。
このずれを解消する方法を、jQueryを使った方法とCSSを使った方法の、2パターンご紹介いたします。
固定ヘッダーを実装している際にアンカーリンクの位置がずれるのを解消する方法
jQueryを使ったずれの解消法
jQueryを使ってずれを解消する場合、移動先の位置を取得した際に、ヘッダーの高さ分位置をずらしてあげます。
何も対策していないアンカーリンク用のコードがこちら↓
<script>
$(function(){
$(".internallink").click(function(){
$("html,body").animate({ scrollTop: $($(this).attr("href")).offset().top }, 800 ,"swing");
return false;
})
});
</script>
internallinkクラスが付いているアンカーリンクをクリックしたら、滑らかに移動します。ただ、このままだと、固定ヘッダーの高さ分位置がずれてしまうので、以下のように固定ヘッダーの高さを移動先までの座標から差し引いてあげます。
<script>
$(function(){
if($(window).width() < 468) {
var headerHight = 100;
} else {
var headerHight = 150;
}
$(".internallink").click(function(){
$("html,body").animate({ scrollTop: $($(this).attr("href")).offset().top-headerHight }, 800 ,"swing");
return false;
})
});
</script>
headerHightの値を固定ヘッダーの高さにします。上記の場合、横幅が468px未満のブラウザでは100px、それ以外では150pxを移動先までの座標から差し引きます。
これで固定ヘッダーが要素に被って、位置がずれてしまうのを防ぐことができます。
CSSを使ったずれの解消法
上記はjQueryを使った解消法ですが、CSSのbefore疑似要素を使ってずれを解消する方法もあります。
例えば、各section要素が移動先だとすると、CSSでは以下のように指定します。
section:before {
content: "";
height: 100px;
margin-top: -100px;
display: block;
visibility: hidden;
}
もちろんsection要素ではなく、IDやクラスなどで指定してもOKです。重要なのは「height」と「margin-top」で、heightで固定ヘッダーの高さ分要素の上に余白を作り、margin-topでマイナスの値を指定し相殺しています。上記の場合は100pxですが、環境に合わせて値は変更してください。
これにより見た目上は変わらなくても、要素の上に固定ヘッダーの高さ分の余白ができ、アンカーリンクの移動先は余白部分になります。そのため、固定ヘッダーの高さ分のずれが解消できるというわけです。
あとがき
最近は、案件でも固定ヘッダーを実装する機会が増えてきました。たしかにナビゲーションが常に表示されていると便利ですよね。便利な反面、アンカーリンクの移動位置がずれてしまうという問題もあるので、しっかりと対策しておきたいですね。

