零弐壱蜂

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

はじめに

CSSの scroll-padding-top と scroll-margin-top プロパティについて解説する。まず、これらのプロパティを理解する上で重要となる「スクロールコンテナ」と「スナップターゲット」について、簡単に説明する。

  • スクロールコンテナ (Scroll Container): スクロールが発生する親要素のことである。通常、html 要素や body 要素、あるいはCSSの overflow プロパティによってスクロールが有効になっている要素(例: overflow: scroll;overflow: auto; が指定された div 要素など)がこれに該当する。このコンテナ内でコンテンツがスクロールする。
  • スナップターゲット (Snap Target): スクロールスナップが発生する際に、スクロールコンテナの特定の位置(スナップポート)に吸着するように停止する対象となる子要素のことである。これらの要素は、スクロールコンテナ内で特定の位置に「スナップ」する。

ページ内リンクやスクロールスナップ時、固定ヘッダによるコンテンツの隠れや不正確な停止位置は問題となることがある。これらをCSSで調整するのが scroll-padding-topscroll-margin-top である。両者は似ているが、役割と適用対象が異なる。

デモ

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

scroll-padding-top とは

scroll-padding-top は、前述のスクロールコンテナに設定する。

スクロールコンテナ上端に内向きの空間を設け、スクロールポートの有効な上端をオフセットする。これにより、ページ内リンクやスクロールスナップ時の要素の停止位置が下にずれる。

主な特徴:

  • 設定対象: スクロールコンテナ
  • 効果: スクロールポートの有効な上端(スナップ基準点)を調整
  • 用途: 固定ヘッダによるコンテンツ隠れの防止

短いコード例:

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

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

scroll-margin-top とは

scroll-margin-top は、前述のスナップターゲットとなる子要素に設定する。
スナップターゲット要素の上部にマージンを設け、スナップ計算上の位置に影響を与える。指定値だけ手前(上)で停止するように見える。

主な特徴:

  • 設定対象: スクロールスナップする子要素(スナップターゲット)
  • 効果: 個々の要素スナップ時の上部オフセットを指定
  • 用途: 特定要素のスナップ位置微調整、要素ごとのオフセット設定

短いコード例:

/* スナップ対象の要素に設定 */
.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:固定ヘッダ環境下で、特定のアンカーリンク先の表示位置をさらに調整する (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:スナップターゲット要素に設定し、個々の表示位置オフセットを調整する。

参考