【jQuery】固定ヘッダーの高さを取得してコンテンツ位置を調整する完全ガイド|ページ内リンク・スクロール・レスポンシブまで

【jQuery】ヘッダーの高さを取得してコンテンツ位置を調整する方法 jQuery

position: fixedposition: sticky の固定ヘッダーがあると、ページ内リンクでジャンプした際にコンテンツがヘッダーの下に隠れてしまいます。この記事ではヘッダー高さの取得・scroll-margin-topによるCSS解決・jQueryでのアンカースクロール補正・レスポンシブ対応まで解説します。

この記事でわかること

  • 固定ヘッダーの高さをjQueryで取得する
  • scroll-margin-top(CSSのみ)で固定ヘッダーを考慮したスクロールにする
  • jQueryでページ内リンクのスクロールをヘッダー高さ分補正する
  • ウィンドウリサイズ時にヘッダー高さを再取得する
  • CSS変数で動的にヘッダー高さを管理する
スポンサーリンク

ヘッダーの高さをjQueryで取得する

$(function () {
  // outerHeight() でpaddingとborderを含む高さを取得
  var headerH = $('#site-header').outerHeight();
  console.log('ヘッダーの高さ:', headerH, 'px');

  // CSS変数にセット(CSS側から参照できるようにする)
  document.documentElement.style.setProperty('--header-height', headerH + 'px');
});
CSS変数でヘッダー高さをCSSとJSで共有
JavaScriptで取得したヘッダー高さを --header-height などのCSS変数にセットすると、CSSの padding-top: var(--header-height) などで参照できます。JSとCSSの値を一元管理でき、メンテナンス性が上がります。

CSS scroll-margin-top で解決する(最も簡単)

Modern CSS の scroll-margin-top を使うと、jQueryなしでジャンプ先の位置を調整できます。

/* ヘッダーが60pxの場合 */
:target {
  scroll-margin-top: 60px;
}

/* CSS変数を使う場合 */
:target {
  scroll-margin-top: var(--header-height, 60px);
}
:targetセレクターは#id でジャンプした要素に適用
:target 疑似クラスはURLの #section-id で指定された要素にマッチします。scroll-margin-top は全モダンブラウザで対応しており、最もシンプルな解決策です。

jQueryでページ内リンクのスクロールを補正する

$(function () {
  // ページ内リンク(#始まり)のクリックをjQueryで制御
  $('a[href^="#"]').on('click', function (e) {
    var href = $(this).attr('href');
    if (href === '#') return; // ページトップリンクはデフォルト動作

    e.preventDefault();

    var $target  = $(href);
    if ($target.length === 0) return; // 対象要素がなければスキップ

    var headerH  = $('#site-header').outerHeight();
    var targetTop = $target.offset().top - headerH - 8; // 余白8px

    $('html, body').animate({ scrollTop: targetTop }, 400);
  });
});

ウィンドウリサイズ時にヘッダー高さを再取得する

スマホでは横・縦持ち切り替えでヘッダー高さが変わることがあります。また、CSSメディアクエリでヘッダーの高さが変わる場合も再取得が必要です。

function debounce(fn, delay) {
  var timer;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(fn, delay);
  };
}

$(function () {
  function updateHeaderHeight() {
    var h = $('#site-header').outerHeight();
    document.documentElement.style.setProperty('--header-height', h + 'px');
    $('body').css('padding-top', h); // bodyのpaddingも更新
  }

  $(window).on('resize', debounce(updateHeaderHeight, 200));
  updateHeaderHeight(); // 初回実行
});

bodyにpadding-topを追加してコンテンツが隠れないようにする

$(function () {
  var headerH = $('#site-header').outerHeight();

  // bodyにpaddingを追加して固定ヘッダー分のスペースを確保
  $('body').css('padding-top', headerH);

  // レスポンシブ: ヘッダーがfixedの場合のみpadding付加
  function adjustPadding() {
    var $header = $('#site-header');
    var isFixed = $header.css('position') === 'fixed' ||
                  $header.css('position') === 'sticky';

    $('body').css('padding-top', isFixed ? $header.outerHeight() : 0);
  }

  $(window).on('resize', debounce(adjustPadding, 200));
  adjustPadding();
});

まとめ

固定ヘッダーとコンテンツ位置調整のポイントをまとめます。

  • 高さ取得: $("#header").outerHeight()
  • CSSのみ解決: :target { scroll-margin-top: 60px }(最もシンプル)
  • jQueryスクロール補正: offset().top からヘッダー高さを引く
  • CSS変数で共有: document.documentElement.style.setProperty("--header-height", h+"px")
  • レスポンシブ: debounceで resize 時に再取得

関連記事: スムーズスクロール完全ガイド / 指定した要素の幅・高さを取得する完全ガイド

よくある質問(FAQ)

Qページ読み込み時のアンカーリンクでも補正したいです。
AURLに最初から #section が含まれている場合は、ページ読み込み後にスクロール位置を再調整します:if (location.hash) { var $t = $(location.hash); $("html,body").scrollTop($t.offset().top - headerH - 8); }最も簡単な対応は :target { scroll-margin-top: var(--header-height) } のCSS解決です。
Qスクロール中にヘッダーが小さくなります(ヘッダーシュリンク)。
Aスクロールでヘッダーの高さが変わる場合は、スクロールイベントでも高さを再取得する必要があります。または CSS変数に縮小後のヘッダー高さを設定してCSSで管理する方法もあります。Cocoonテーマなどを使っている場合はテーマのヘッダー設定も確認してください。
Qアンカーリンクの補正がWordPressで効きません。
AWordPressでは他のプラグインやテーマが a[href^="#"] のスクロールを既に制御している場合があります。e.stopPropagation() を追加するか、先に定義されたイベントを .off("click") で解除してから再定義してください。また、Cocoonテーマにはスムーズスクロール機能が内蔵されています。
Qモバイルのみヘッダーが固定でPCは固定でない場合はどうすれば?
ACSSの position プロパティを取得してfixedかどうかを判断します:if ($("#header").css("position") === "fixed") { ... }またはウィンドウ幅で条件分岐してください:if ($(window).width() < 768) { ... }
Q目次リンクのスクロール補正はどこに書けばよいですか?
Aテーマの functions.phpwp_enqueue_script() を使い、カスタムJSファイルを読み込む方法が推奨です。または子テーマの style.css の末尾に <style> タグでCSSのscroll-margin-topを追加する方法もシンプルです。