ページ内リンクの飛び先が固定ヘッダーに隠れないCSS|scroll-margin-topとscroll-padding-topの使い分け3種類

ページ内リンクの飛び先が固定ヘッダーに隠れない見本とコード

目次のリンクを押したら、飛んだ先の見出しが、上に固定したヘッダーの裏に隠れてしまう。上に固定するヘッダーを使うと、よく起きることです。CSSの1行で、ヘッダーの下に見出しが来るように直せます。

使いどころは、上に固定したヘッダーがあり、目次やページ内リンクも使っているページです。固定ヘッダーがないページには要りません。数値は「ヘッダーの高さ+少しの余白」にします。

この記事の要点

  • scroll-margin-top(飛び先に付ける)か scroll-padding-top(ページ全体に付ける)で、ページ内リンクの飛び先を、固定ヘッダーの下に止められる
  • 使いどころは、上に固定したヘッダーと、目次などのページ内リンクの両方があるページ。数値は「ヘッダーの高さ+余白」
  • ヘッダーの高さがスマホとPCで違うなら、数値も合わせて変える。なめらかに飛ばすのは、動きを減らす設定にしていない人だけにする
トミー

連載「WEBの技術」の53回目です。
16回目の「ヘッダーを上に固定する」の続きの話です。ヘッダーを固定したら、目次のリンクも一緒に確かめてください。

完成見本:飛び先が隠れないようにする3種類

小さな画面の絵で、目次のリンクを押したところを自動でくり返しています。1は、左が指定なし、右が指定ありです。2は、3つの見出しへ順番に飛んでいます。3は、なめらかに動いて、着いた見出しに色が付きます。

SCROLL MARGIN1. 飛び先の見出しに付ける特定の見出しだけ、位置を直したいときに
SCROLL PADDING2. ページ全体にまとめて付ける目次のある記事、縦に長い1ページのサイトに
SMOOTH + TARGET3. なめらかに飛んで、着いた所を知らせるスマホとPCでヘッダーの高さが違うサイトに

※ 見本は、動きを見せるための絵です(読み上げソフトでは読まれないようにしています)。動きを減らす設定にしている方には、飛んだあとの形で止まって見えます。実際に押して試せる見本は、コードのあとにあります。

コピペ用のコード

CSSは、サイトのCSSファイルや、WordPressならテーマの「追加CSS」などに入れます。HTMLの href="#price" の price と、見出しの id="price" を同じ名前にすると、そのリンクで見出しへ飛びます。数値の 80px は、高さ64pxの固定ヘッダーの例です。自分のサイトのヘッダーの高さに合わせて変えます。

1. 飛び先の見出しに付ける

飛び先の見出し(id を付けた要素)に scroll-margin-top を付けます。「この要素へ飛んできたときは、上にこれだけ空けて止まる」という指定です。数値は、固定ヘッダーの高さに、少しの余白を足したものにします。

HTML
<nav class="kd-sm-toc">
  <a href="#price">料金</a>
  <a href="#flow">ご依頼の流れ</a>
  <a href="#faq">よくある質問</a>
</nav>

<h2 id="price" class="kd-sm-target">料金</h2>
<p>…</p>

<h2 id="flow" class="kd-sm-target">ご依頼の流れ</h2>
<p>…</p>

<h2 id="faq" class="kd-sm-target">よくある質問</h2>
<p>…</p>
CSS
/* 飛び先の見出しに付ける */
.kd-sm-target {
  scroll-margin-top: 80px; /* ヘッダー64px + 余白16px */
}

2. ページ全体にまとめて付ける

スクロールする側(ページ全体なら html)に scroll-padding-top を付けます。「この画面の上から80pxは、ヘッダーで隠れている」と伝える指定です。見出しごとにクラスを付けなくても、どの id へ飛んでも、ヘッダーの下に止まります。

HTML
<nav class="kd-sm-toc">
  <a href="#price">料金</a>
  <a href="#flow">ご依頼の流れ</a>
  <a href="#faq">よくある質問</a>
</nav>

<h2 id="price">料金</h2>
<p>…</p>

<h2 id="flow">ご依頼の流れ</h2>
<p>…</p>

<h2 id="faq">よくある質問</h2>
<p>…</p>
CSS
/* ページ全体にまとめて付ける */
html {
  scroll-padding-top: 80px; /* ヘッダー64px + 余白16px */
}

3. なめらかに飛んで、着いた所を知らせる

2の形に、3つ足します。ヘッダーの高さを変数(--kd-header-h)にして、スマホでは低い値に入れかえる。動きを減らす設定にしていない人には、scroll-behavior: smooth でなめらかに飛ばす。着いた見出しは、:target(URLの # の先にある要素)で少しのあいだ色を付けて知らせます。

HTML
<nav class="kd-sm-toc">
  <a href="#price">料金</a>
  <a href="#flow">ご依頼の流れ</a>
  <a href="#faq">よくある質問</a>
</nav>

<h2 id="price">料金</h2>
<p>…</p>

<h2 id="flow">ご依頼の流れ</h2>
<p>…</p>

<h2 id="faq">よくある質問</h2>
<p>…</p>
CSS
/* ヘッダーの高さを変数にする */
:root {
  --kd-header-h: 64px;   /* PC */
}
@media (max-width: 767px) {
  :root {
    --kd-header-h: 52px; /* スマホ */
  }
}
html {
  scroll-padding-top: calc(var(--kd-header-h) + 16px);
}

/* 動きを減らす設定の人には、なめらかにしない */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* 着いた見出しを、少しのあいだ色で知らせる */
h2:target {
  animation: kd-sm-flash 1.6s ease-out;
}
@keyframes kd-sm-flash {
  from { background-color: #E0F2FE; }
  to   { background-color: transparent; }
}

実際に押して試せる見本

枠の中に、高さ48pxの固定ヘッダーがあります。ボタンを押すと、下の見出しへ飛びます。チェックを外すと scroll-margin-top が外れて、見出しがヘッダーの裏に入ります。

SHOP
上のボタンで、下の見出しへ飛びます。

料金

基本のプランは、ページ数とお急ぎかどうかで決まります。

ご依頼の流れ

ご相談、お見積もり、制作、公開の順に進みます。

よくある質問

公開のあとの更新も、ご相談ください。

この見本だけは、記事のページ全体が動かないように、短いJSで枠の中だけを動かしています。実際のサイトでは、JSなしの普通のリンク(<a href="#price">)で同じ動きになります。

仕組み:ブラウザは「見出しを画面のいちばん上へ」動かす

ヘッダーの裏に隠れる理由

ページ内リンクを押すと、ブラウザは、飛び先の要素の上の端が画面のいちばん上に来るように動かします。ところが、position: sticky や fixed で固定したヘッダーは、ページの上に重なって表示されています。そのため、見出しはちゃんと画面の上まで来ているのに、ヘッダーの裏に入って見えなくなります。

scroll-margin-top:飛び先に「上の余白」を足す

scroll-margin-top は、スクロールで止まるときだけに使う、要素の上の余白です。見た目の余白(margin)は変わりません。W3Cの仕様(CSS Scroll Snap)では、ページ内リンクで飛ぶときも、この余白を含めた範囲を画面に入れることになっています。80pxにすると、見出しの上に80px空けた位置で止まります。

scroll-padding-top:画面の上の「隠れている範囲」を伝える

scroll-padding-top は、スクロールする側に付けます。MDNは、固定されたツールバーなどで隠れている範囲を、表示の対象から外すためのものと説明しています。ページ全体なら html に付けます。どの見出しへ飛んでも同じように効くので、目次の多い記事はこちらが楽です。

MDNの対応表では、どちらも2021年4月からBaseline(主なブラウザで広く使える)になっています。2026年11月10日に確認しました。

なめらかに飛ぶのは scroll-behavior

scroll-behavior: smooth を html に付けると、ページ内リンクで飛ぶときに、なめらかに動きます。MDNによると、body に付けても画面全体には効きません。また、ブラウザがこの指定を使わないことも認められています。なめらかに動かなくても困らない作りにしておきます。

数値を変えるとどうなるか

高さ40pxのヘッダーの絵で、余白の数値だけを変えました。

見出しが隠れる
ぎりぎりで窮屈
今回の見本

左の0pxは、見出しがヘッダーの裏に隠れています。真ん中は、ヘッダーと同じ40pxです。見出しは見えますが、ヘッダーにくっついて窮屈です。右の52pxのように、ヘッダーの高さに12〜16pxほど足すと、どこへ飛んだのかが分かりやすくなります。

反対に、余白を大きくしすぎると、見出しの上に前の段落の終わりが見えて、どこから読めばよいのかが分かりにくくなります。足すのは、見出しと本文の間の余白と同じくらいが目安です。

スマホと、見る人への配慮

ヘッダーの高さは、スマホとPCで違うことが多い

PCでは64px、スマホでは52pxのように、ヘッダーの高さが画面の幅で変わるサイトは多くあります。3のように高さを変数にして、@media で入れかえると、数値を1か所で直せます。ヘッダーの高さを変えたときに、ここも一緒に直すのを忘れないようにします。

キーボードで操作する人のためにも効く

Tabキーでリンクやボタンを順に選んでいくと、選ばれた部品が、固定ヘッダーの裏に入ってしまうことがあります。W3Cは、これを防ぐ方法の1つとして、scroll-padding を使う例(Technique C43)を挙げています。html に scroll-padding-top を付けておくと、ページ内リンクとキーボード操作の両方に効きます。

なめらかな動きは、動きを減らす設定の人には出さない

3では、scroll-behavior: smooth を @media (prefers-reduced-motion: no-preference) の中に入れています。iPhoneの「視差効果を減らす」をオンにしている人や、Windows 11の「アニメーション効果」をオフにしている人など、動きを減らす設定の人には、なめらかにせず一瞬で飛ばします。長いページで大きく動く画面は、酔いやすい人にはつらい動きです。

やりすぎ注意

ヘッダーを固定すると、スマホでは画面の高さのうち、毎回その分が使えなくなります。今回の直し方は、ヘッダーを固定した「あと」の手当てです。ヘッダーそのものが高すぎるなら、先にそちらを低くします。

AIに頼むなら

Claudeなどの生成AIに頼むときは、ヘッダーの高さ、スマホとPCの違い、動きの配慮まで伝えると、手直しが減ります。

固定ヘッダー(PCは64px、スマホは52px)があるページで、目次のリンクの飛び先がヘッダーに隠れないようにして。
html に scroll-padding-top を付けて、ヘッダーの高さは変数に。
なめらかに飛ばすのは prefers-reduced-motion: no-preference のときだけにして。

AIが出したコードは、そのまま使う前に、次の3つを確かめます。

  • 数値が、今のヘッダーの高さと合っているか。スマホの幅でもヘッダーの高さを測り、目次のリンクを全部押してみます
  • 見出しに、余白を作るためだけの空の要素や、マイナスのmarginが足されていないか。古い直し方です。今は scroll-margin-top か scroll-padding-top の1行で済みます
  • 動きを減らす設定で、なめらかに動いていないか。OSの設定をオンにして、一瞬で飛ぶかを確かめます

KAKERUならこう使う/使わない

最後に、作り手としての判断です。

使う場面

  • 上に固定したヘッダーがあるサイト全体。html に scroll-padding-top を1行入れておきます。目次のリンクにも、キーボード操作にも効きます
  • 目次のある長い記事や、サービス紹介の縦に長いページ。押したあと、読みはじめる見出しがすぐ目に入ることが大事です
  • 一部の見出しだけ、上に飾りや帯があるとき。その見出しにだけ scroll-margin-top を足して、飾りまで見える位置で止めます

使わない場面

  • ヘッダーを固定していないページ。隠れるものがないので要りません。余白だけが空いて、かえって分かりにくくなります
  • ヘッダーの高さが毎回変わる作り(スクロールで縮む、お知らせの帯が出たり消えたりするなど)。1つの数値では合わせきれません。先にヘッダーの作りを見直します
  • 「なめらかに動くと高級に見える」という理由だけの scroll-behavior。長いページでは、一瞬で飛ぶほうが早く読みはじめられます。入れるなら3のように、動きを減らす設定に合わせます
トミー

KAKERUなら、ヘッダーを固定するときに、この1行を最初から一緒に入れます。
公開前に、目次のリンクをスマホとPCで全部押して確かめるところまでが、ヘッダーの作業です。

まとめ

  • ページ内リンクの飛び先は、画面のいちばん上に来るので、固定ヘッダーの裏に隠れる
  • 飛び先に scroll-margin-top、またはページ全体(html)に scroll-padding-top を付けて直す
  • 数値は「ヘッダーの高さ+12〜16px」。スマホとPCで高さが違うなら、変数にして入れかえる
  • scroll-padding-top は、キーボード操作で選んだ部品が隠れるのを防ぐ助けにもなる
  • なめらかに飛ばすのは、動きを減らす設定にしていない人だけにする

まずは2のコードをコピーして、80pxを自分のサイトのヘッダーの高さ+16pxに変えてみてください。目次のリンクを押せば、すぐに違いが分かります。

参考にした資料

いずれも2026年11月10日に確認しました。内容は変わることがあります。最新の情報は各ページでご確認ください。

ふだんの制作の話や、作ったものの裏側は Instagram と X でも出しています。

関連記事

ヘッダーを上に固定するCSS。position: stickyが止まらない原因と、使う・使わないの判断
ページの一番上に戻るボタン。置く・置かないの判断と、押しやすい大きさ
動きが苦手な人への配慮をCSSで。ふつうの見え方と動きを減らす設定の見え方を並べた見本とコード
ページ内リンクの飛び先が固定ヘッダーに隠れない見本とコード

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA