Blog

ページ内リンクがずれる原因と直し方|jQueryで苦労した備忘録とCSSのscroll-margin-top

2026/11/02

JQuery css

ページ内リンクがずれる原因と直し方|jQueryで苦労した備忘録とCSSのscroll-margin-top

リンクを押したのに、見出しが隠れている

ページの上に「目次」や「お問い合わせはこちら」のボタンがあって、押すと同じページの中の該当箇所まで移動する。これをページ内リンク(アンカーリンク)と呼びます。

とても身近な仕組みなのですが、実はトラブルの多い部分でもあります。よくあるのは次の2つです。

  • 移動はするけれど、見出しが上の固定ヘッダーに隠れて読めない
  • 目的の場所とは違うところで止まってしまう

私のブログを読み返すと、このページ内リンクの備忘録が、2015年、2017年、2023年と3回も出てきました。

今回はその3本を振り返りながら、ズレが起きる理由と、いまのCSSならどう直せるのかを、初心者の方にも分かるようにまとめます。

私がページ内リンクでつまずいた3回

2015年:スマホだけ、ページ内リンクが飛ばない

ECCUBEで作るネットショップのスマホ対応で、商品詳細ページのページ内リンクが動かないことに気づきました。調べていくと、スマホ用の画面で使われていたjQuery Mobileが関係しており、専用のスクリプトを書いて解決しました。

調査と修正に少し時間がかかり、備忘録には「PCと同じように構築して、動作しないとちょっと焦りますね」と書いています。同じ作り方をしても、環境が違えば同じようには動かない。そのことを実感した案件でした。

2017年:jQueryのバージョンで書き方が変わる

クリックするとスーッと滑らかに移動する「スムーズスクロール」も、当時はjQueryで書くのが定番でした。

このときの備忘録に残したのは、jQueryのバージョンによって記述が少し違うという話です。# をダブルクォーテーションで囲まないといけない場合がありました。たった2文字の違いで動かなくなるので、「先にjQueryのバージョンを確かめる」とメモしています。

2023年:フォームに飛ばず、上の別の項目で止まる

3回目は、原因の切り分けが必要でした。あるランディングページ(1枚の縦長のページ)にカスタム投稿の一覧を入れたところ、最下部のフォームに移動するはずのリンクが、上にある別の項目で止まるようになりました。

試しに一覧を非表示にすると、きちんとフォームまで移動します。そこで「一覧の高さが原因」と判断しました。

ところが、検索して出てくるのは固定ヘッダーのズレを直す記事ばかりで、特定のエリアの高さを差し引く方法は見つかりません。結局、固定ヘッダー用のスクリプトを改造して、エリアの高さの分だけ移動先を調整しました。

なお、当時の備忘録に載せたのはスクリプトの一部だけで、そのままコピーしても動かない形でした。読者の方には申し訳なかったと思っています。

なぜページ内リンクはずれるのか

ここからは一般的な話として、原因を整理します。

原因1:固定ヘッダーの下に潜り込んでいる

ブラウザは、移動先の要素を画面のいちばん上に合わせようとします。ところが、スクロールしても上に残り続ける固定ヘッダーがあると、その分だけ見出しが隠れてしまいます。ブラウザはヘッダーの高さを考えてくれないのです。

原因2:移動したあとに、ページの高さが変わる

画像の遅延読み込みや、あとから表示される一覧、広告などがあると、スクロールの途中でページが縦に伸びることがあります。移動先の位置を先に計算して動かす方法だと、その間に目的地が下へずれ、手前で止まって見えます。

2023年の私の件も、一覧の高さが関係していたのは確かです。ただ、なぜ止まる位置が変わったのかまでは、備忘録に書いておらず、はっきりしません。この原因2だった可能性はあります。

原因3:JavaScriptが標準の動きを横取りしている

jQueryのスムーズスクロールは、ブラウザ標準の移動を止めて、自分で計算した位置へ動かす仕組みです。そのため、計算がずれれば、そのまま移動先もずれます。

いまならCSSで直せる

私がjQueryで苦労していたことの多くは、いまならCSSだけで解決できます。当時の私はこの方法をまだ使っていませんでした。

ページ全体をまとめて調整:scroll-padding-top

固定ヘッダーが高さ80pxなら、少し余裕を持たせて次のように書きます。

html {
  scroll-padding-top: 90px;
}

これで、ページ内リンクで移動したときに、上に90pxの余白を空けて止まります。ほとんどの固定ヘッダーの問題は、これだけで片付きます。

特定の場所だけ調整:scroll-margin-top

一部の要素だけ調整したいときは、移動先のほうに書きます。

#contact {
  scroll-margin-top: 120px;
}

2023年に私が求めていた「特定のエリアを指定して調整する」に近いのは、こちらの書き方です。もちろん、私の件の原因が高さの変化だったとすれば、余白の調整だけでは解決しない場合もあります。

スムーズスクロールもCSSで

滑らかな移動もjQueryなしで書けます。

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

prefers-reduced-motion の部分は、パソコンやスマホの設定で「動きを減らす」を選んでいる方には滑らかな移動をしない、という配慮です。

CSSにすると、ここが楽になる

  • 計算が要らないので、スクリプトを書かなくて済む
  • 別のページから page.html#contact のように直接来たときにも効く(クリック時だけ動くスクリプトでは、ここが抜けやすい)
  • jQueryのバージョンに左右されない

外部の部品に頼る部分が減れば、将来壊れる場所も減ります。2022年には、jQueryで動くスライダーのBoxsliderが動かなくなったこともありました。

直すときに確認したいこと

古いスクリプトを残したままにしない

jQueryのスムーズスクロールが残っていると、CSSの設定が効かなかったり、動きがぎくしゃくしたりすることがあります。CSSに切り替えるなら、古いスクリプトを外してから確認します。

スマホではヘッダーの高さが違う

スマホとパソコンでヘッダーの高さが違うなら、余白も分けて指定します。

html {
  scroll-padding-top: 90px;
}
@media (max-width: 768px) {
  html {
    scroll-padding-top: 60px;
  }
}

WordPressはログアウトして確認する

WordPressにログインしていると、画面の上に管理バーが表示されます(パソコンで高さ32px、スマホ幅では46px)。そのため「自分の画面だけ少しずれる」ということが起こります。確認はログアウトした状態か、シークレットウィンドウで行うと確実です。

そもそも動かないときは、ここを見る

位置がずれるのではなく、まったく移動しないときは次を確認します。

  • リンクの #contact と、移動先の id="contact" の綴りが一致しているか
  • 同じ id がページ内に2つ以上ないか
  • 移動先が display: none で隠れていないか

ブラウザのコンソール(F12)を開いて、JavaScriptの赤いエラーが出ていないかも見ておきます。

まとめ

  • ページ内リンクのズレは、固定ヘッダー、ページの高さの変化、JavaScriptの計算のどれかが原因のことが多い
  • 固定ヘッダーで隠れるだけなら、scroll-padding-top の1行から試す
  • 特定の場所だけ調整するなら、scroll-margin-top
  • スムーズスクロールも scroll-behavior: smooth で書ける
  • CSSに替えるときは古いスクリプトを外し、スマホとログアウト状態でも確認する

3本の備忘録を読み返して、同じページ内リンクでも、悩みの中身は時代とともに変わってきたのだと感じました。いま同じトラブルに出会ったら、私はまずCSSから試すと思います。

カテゴリー

月間アーカイブ

MORE

神社仏閣ホームーページ制作

ホームページ制作問合せ