ページ内リンクのジャンプ先がずれる原因と解決方法【HTML】

ページ内リンクのジャンプ先がずれてしまう原因と、その解決策について解説します。

別ページの特定の場所にリンクを貼る場合には、ハッシュ(#)で要素のIDを指定しますよね。
例えば、こういう感じで。

<a href="../sample.html#example">サンプル</a>

もちろん、これはHTMLの文法的には正解で、なんの間違いもありません。

でも、実は、これだけでは不十分なケースもあるんです。

例えば、レスポンシブデザインを採用しているケースです。

レスポンシブデザインの弊害

レスポンシブデザインのサイトでは、ウィンドウサイズに応じて画像サイズが動的に変更されます。

画像の幅は親要素と同じ、高さはそれに合わせて自動で調整するという指定の仕方が一般的です。

img{
  width:100%;
  height:auto;
}

このように指定しておけば、あとはブラウザがうまいこと表示してくれるので、とても便利なわけです。

でも、これには弊害もあって、ページを読み込んでみないと画像の高さが決まらないんです。
width:100%が何ピクセルなのか、それが決まらないと高さも決まりません。

そして、ここにページ内リンクのジャンプ先がずれてしまう原因があります。

ズレの原因

ブラウザがジャンプ先の位置を計算する段階では、画像の高さが決まっていません。
その段階では画像の高さは0。

そして、ジャンプした後に画像が読み込まれて、その画像の高さ分のズレが生じることになります。

これがズレの原因です。

ズレの解決方法

さて、ではどのようにズレをなくすか。

ページ内リンクのジャンプ先のズレを解消する方法は2つあります。

  • サイトをAMP化する
  • javascriptで対応する

AMP化による解決

AMP(Accelerated Mobile Pages)で画像を表示するときには、<img>ではなく、<amp-img>を使います。

<amp-img>の素晴らしいのは、レスポンシブであっても高さが0にはならないという点です。

ページ内リンクのジャンプ先の位置を計算する際にも、しっかりと画像の高さを確保してくれるんです。

もし、AMPを導入することが可能なら、これがいちばん良い選択肢だと思います。

javascriptで対応する

とは言っても、AMP化は技術的にもハードルが高いですし、制約も少なからず発生します。

そこで、次の手としては、javascriptによる対応です。

ページの読み込み完了後に、強引にスクロールさせてズレを解消します。

<script type="text/javascript">
window.onload = function() {
    if(window.location.hash==""){return;}
    document.getElementById(window.location.hash.slice(1)).scrollIntoView(true);
};
</script>

WordPressなら、functions.phpに次のコードを追記すると便利です。

add_action('wp_footer', function(){
    $code = <<< EOF
<script type="text/javascript">
window.onload = function() {
    if(window.location.hash==""){return;}
    document.getElementById(window.location.hash.slice(1)).scrollIntoView(true);
};
</script>
EOF
;
    echo $code;
});

以上、ページ内リンクのジャンプ先がずれる原因と解決方法でした。

コメント

この記事についてのご感想などをお寄せください。
サイト運営の参考にさせていただきます。
頂いたコメントには、2〜3日以内にメールアドレス宛に回答いたします。(詳細
メールアドレスの入力ミスにご注意ください。
なお、頂いたコメント及びその後のメール等でのやり取りは、この欄でご紹介させていただく場合がございます。