零弐壱蜂

[CSS] scroll-padding-top と scroll-margin-top の違いと使い分け

はじめに

固定ヘッダがあるページで、ページ内リンクをクリックすると、リンク先のコンテンツがヘッダに隠れてしまうことがある。また、スクロールスナップ(スクロール時に特定の位置で自動的に止まる機能)を使う際も、停止位置のずれという問題が発生する。これらを解決するCSSプロパティが scroll-padding-topscroll-margin-top である。

この2つのプロパティの主な違いは、設定する場所にある。scroll-padding-top はスクロールコンテナに、scroll-margin-top はスナップターゲットに設定する。

スクロールコンテナとスナップターゲット

これらの用語を理解することで、2つのプロパティの使い分けが明確になる。

  • スクロールコンテナ: スクロールが発生する親要素のこと。通常、html 要素や body 要素、あるいはCSSで overflow: scroll;overflow: auto; が指定された要素がこれに該当する。
  • スナップターゲット: スクロールスナップを使う際に、特定の位置で止まる対象となる子要素のこと。例えば、画像ギャラリーで各画像がスナップターゲットとなり、スクロール時に画像の位置で自動的に止まる。

デモ

scroll-padding-topscroll-margin-top の違いを示すデモは以下。

scroll-padding-top とは

scroll-padding-top は、スクロールコンテナに設定するプロパティである。

スクロールコンテナの上端に余白を設ける。これにより、ページ内リンクやスクロールスナップの停止位置が、設定した余白と同じだけ下にずれる。

主な特徴:

  • 設定対象: スクロールコンテナ(htmlbodyoverflowが指定された要素など)
  • 効果: スクロール時の停止位置を下方向にずらす
  • 用途: 固定ヘッダによるコンテンツの隠れを防ぐ

短いコード例:

/* スクロールコンテナ (例: html要素) に設定 */
html {
  scroll-padding-top: 60px; /* スクロール時の上部の余白を60pxに設定 */
}

例えば、scroll-padding-top: 60px; を設定すると、リンク先のセクション上端がビューポート最上部から 60px 下に表示される。

scroll-margin-top とは

scroll-margin-top は、スナップターゲットとなる子要素に設定するプロパティである。

スナップターゲット要素の上部にマージンを設ける。これにより、その要素がスナップする際、設定した値と同じだけ上でスナップする。

主な特徴:

  • 設定対象: スナップターゲット(sectionarticledivなどのスナップする要素)
  • 効果: 個々の要素のスナップ位置を上方向にずらす
  • 用途: 特定要素のスナップ位置を個別に調整する

短いコード例:

/* スナップ対象の要素に設定 */
.snap-target-item {
  scroll-margin-top: 20px; /* この要素がスナップする際、上部に20pxの余白を設ける */
}

例えば scroll-margin-top: 20px; を設定すると、そのセクションは実際の上端から 20px 上でスナップする。

scroll-padding-top と scroll-margin-top の主な違い

特徴scroll-padding-topscroll-margin-top
設定対象スクロールコンテナ (例: html, body, divスナップターゲット要素 (例: section, article, div
影響範囲スクロールコンテナ全体のスクロール停止位置個々のスナップターゲット要素のスナップ位置
主な目的固定ヘッダ対策など、コンテナ全体の表示領域調整特定要素のスナップ位置の微調整

実践的ユースケース

ケース1:固定ヘッダとページ内リンク (scroll-padding-top)

固定ヘッダがある場合、ページ内リンク先がヘッダに隠れることがある。

  • 問題点: ページ内リンク先が固定ヘッダに隠れる。
  • 解決策: スクロールコンテナに scroll-padding-top を設定し、ヘッダ分のオフセットを指定する。

短いコード例:

html {
  scroll-padding-top: 70px; /* 固定ヘッダの高さが70pxの場合 */
}

scroll-padding-top: 70px; で、リンク先がヘッダ高さ分(70px)下に表示され、隠れを防ぐ。

ケース2:特定のセクションのスナップ位置調整 (scroll-margin-top)

スクロールスナップを使う際、特定のセクションだけスナップ位置を変えたい場合がある。

  • 問題点: 全セクションが画面上端にスナップする。特定のセクションだけ、スナップ位置を変えたい。
  • 解決策: 調整したい要素に scroll-margin-top を設定する。

短いコード例:

.special-section {
  scroll-margin-top: 50px; /* このセクションは通常より50px上でスナップする */
}

.special-sectionscroll-margin-top: 50px; を設定すると、その要素はほかより50px手前(上)でスナップする。

ケース3:要素ごとのアンカーリンク位置調整 (scroll-margin-top)

特定のアンカーリンク先要素の上部に余白を持たせたい場合がある。

  • 問題点: アンカーリンク先が画面上端に密着し窮屈である。
  • 解決策: 対象要素に scroll-margin-top で余白を設定する。

短いコード例:

#section-heading {
  scroll-margin-top: 2rem; /* この見出しへのジャンプ時、上部に2remの余白 */
}

#section-headingscroll-margin-top: 2rem; を設定すると、ジャンプ先の上部に2remの余白ができる。これは scroll-padding-top とは独立した設定である。

ケース4:スクロールスナップコンテナ全体のパディング (scroll-padding-top)

スナップコンテナ全体の上部に一律の余白を持たせたい場合がある。

  • 問題点: スナップ要素が、画面上端ギリギリで圧迫感がある。
  • 解決策: スナップコンテナに scroll-padding-top を設定する。

短いコード例:

.snap-container {
  scroll-snap-type: y mandatory;
  scroll-padding-top: 30px; /* スナップコンテナ全体の上部余白 */
}

.snap-containerscroll-padding-top: 30px; を設定する。この設定は、スナップ時にコンテナ上部へ常に30pxの余白を作る。

ケース5:2つのプロパティの併用 (scroll-padding-top と scroll-margin-top)

固定ヘッダ対策に加え、特定の要素だけさらに余白を設けたい場合がある。

  • 問題点: scroll-padding-top だけでは、すべての要素に同じ余白が適用される。特定の要素だけ、さらに余白を追加したい。
  • 解決策: スクロールコンテナに scroll-padding-top を設定後、微調整したい要素に scroll-margin-top を設定する。

短いコード例:

/* 固定ヘッダの高さが60pxの場合 */
html {
  scroll-padding-top: 60px;
}

/* 特定のアンカーターゲット要素 (例: #important-section) */
#important-section {
  /* ヘッダ回避後に、さらに20px上部に余白を設ける */
  scroll-margin-top: 20px;
}

htmlscroll-padding-top: 60px; を設定し、ヘッダ回避。次に #important-sectionscroll-margin-top: 20px; を設定すると、ヘッダ回避位置からさらに20pxの余白ができる。これにより、scroll-padding-top の基準位置から scroll-margin-top 分オフセットされる。

使い分けの判断基準

どちらを使うか迷ったら、以下を考慮する。

  1. 固定ヘッダ対策が必要か?
    → スクロールコンテナに scroll-padding-top
  2. 特定要素のスナップ/アンカー位置をほかと変えたいか?
    → 対象要素に scroll-margin-top
  3. スナップコンテナ全体に一律の余白が必要か?
    → スナップコンテナに scroll-padding-top
  4. 複数要素に異なるオフセットを個別に設定したいか?
    → 各要素に scroll-margin-top
  5. 固定ヘッダ対策+特定アンカーの微調整が必要か?
    scroll-padding-topscroll-margin-top を併用(ケース5参照)

基本的な考え方は、コンテナ全体に影響させたいなら scroll-padding-top、個別要素を調整したいなら scroll-margin-top を使う。また、両者を組み合わせることで、より細かい制御ができる。

論理プロパティ

書字方向を考慮した論理プロパティもある。

  • scroll-padding-block-startscroll-padding-top 相当)
  • scroll-margin-block-startscroll-margin-top 相当)

これらにより、縦書きなどでも意図通りの挙動をさせやすくなる。

まとめ

scroll-padding-topscroll-margin-top はスクロール位置調整に重要である。

  • scroll-padding-top:スクロールコンテナに設定し、全体の有効な上端を調整する。固定ヘッダ対策に有効である。
  • scroll-margin-top:スナップターゲット要素に設定し、個々の表示位置オフセットを調整する。

参考