🐡

CSS変数とJavaScriptを使って、アンカーリンクのジャンプ先の位置を柔軟に調整する

に公開

ウェブサイトでアンカーリンクを使用する際、固定ヘッダーがあると目的の位置に正確にジャンプできないことがあります。この問題を解決するために、CSS変数とJavaScriptを組み合わせた柔軟な方法を紹介します。

解決策の概要

  1. CSS変数を使ってデフォルトのアンカー位置調整値を設定
  2. HTMLで個別の調整を可能にする
  3. JavaScriptを使って動的にスタイルを適用

コードと解説

1. CSS

:root {
    --header-height: 4.125pc;
    --anchor: var(--header-height);
}

@media print, screen and (min-width: 744px) {
    :root {
        --header-height: 8.25pc;
        --anchor: var(--header-height);
    }
}

[anchor] {
    margin-top: calc(var(--anchor) * -1);
    padding-top: var(--anchor);
}

このCSSは、:rootセレクタを使ってグローバルなCSS変数を定義しています。--header-heightはヘッダーの高さを、--anchorはアンカーリンクの調整値を表します。メディアクエリを使用して、画面サイズに応じて値を変更しています。

2. HTML

<!-- デフォルトの調整を使用 -->
<hr id="section1" anchor />

<!-- カスタム値で調整 -->
<hr id="section2" anchor="20pc" />

<!-- インラインスタイルで調整 -->
<hr id="section3" anchor style="--anchor:20pc;" />

HTMLでは、anchor属性を使ってアンカーリンクの調整を適用します。属性値を指定するか、インラインスタイルでCSS変数を上書きすることで、個別の調整が可能です。

3. JavaScript

(function () {
    const elements = document.querySelectorAll('[anchor]');
    const STYLE = document.createElement('style');
    document.head.appendChild(STYLE);

    elements.forEach((el) => {
        const anchorValue = el.getAttribute('anchor');
        let id = el.id || 'anchor-' + Math.random().toString(36).substr(2, 9);
        el.id = id;

        const anchorStyle = `
            #${id} {
                margin-top: calc(-1 * (${anchorValue || 'var(--anchor)'}));
                padding-top: ${anchorValue || 'var(--anchor)'};
            }
        `;

        try {
            STYLE.sheet.insertRule(anchorStyle, STYLE.sheet.cssRules.length);
        } catch (e) {
            console.error(`Failed to insert CSS rule for element with id "${id}": ${e.message}`);
        }
    });
})();

このJavaScriptは以下の手順で動作します:

  1. anchor属性を持つすべての要素を選択
  2. 新しい<style>要素を作成
  3. 各要素に対して:
    • anchor属性の値を取得
    • ユニークなIDを確保
    • CSSルールを生成
    • 生成したルールをスタイルシートに挿入

使い方

  1. CSSをスタイルシートに追加
  2. JavaScriptをページに読み込む
  3. アンカーリンクを調整したい要素にanchor属性を追加
  4. 必要に応じて、属性値やインラインスタイルで個別に調整

利点

  1. 柔軟性: デフォルト値をグローバルに設定しつつ、個別の要素で簡単に調整可能
  2. メンテナンス性: ヘッダーの高さが変更された場合、CSS変数を更新するだけで全体に反映
  3. 再利用性: このスクリプトは様々なプロジェクトで再利用可能
  4. パフォーマンス: JavaScriptによるDOM操作が最小限で、ページ読み込み時に一度だけ実行
  5. 互換性: scroll-padding-topのブラウザサポートに依存せず、幅広いブラウザで動作
  6. デザイナーフレンドリー: HTMLの属性やインラインスタイルで簡単に調整可能

まとめ

この方法を使用することで、アンカーリンクのジャンプ先位置を柔軟かつ効果的に調整できます。CSS変数とJavaScriptの組み合わせにより、開発者とデザイナーの両方にとって使いやすいソリューションとなっています。固定ヘッダーを使用するレスポンシブデザインのウェブサイトで特に有用であり、ユーザーエクスペリエンスを向上させることができます。

Discussion