JavaScriptでCSSのカスタムプロパティを扱ってみる

投稿日:

更新日:

ヘッダーの高さをカスタムプロパティにセットする

index.js
// ヘッダーの高さを取得する
const headerElement = document.getElementById("header");
const headerHeight = headerElement?.offsetHeight ?? 0;

// ヘッダーの高さをカスタムプロパティにセットする
document.documentElement.style.setProperty("--headerHeight", `${headerHeight}px`);

#headerが存在しない場合にoffsetHeightがエラーになるので、オプショナルチェーン(?.)で繋ぎます。
その時にheaderElementundefinedになるので、Null合体演算子(??)で0を代入します。

特定の要素にカスタムプロパティを設定する

index.js
const sectionElement = document.getElementById("section");
const sectionHeight = sectionElement?.offsetHeight ?? 0;

// セクション要素にカスタムプロパティをセットする
sectionElement.style.setProperty("--sectionHeight", `${sectionHeight}px`);

カスタムプロパティの値を取得する

style.css
:root {
  --headerHeight: 60px;
}
index.js
// カスタムプロパティの値を取得する
const headerHeight = getComputedStyle(document.documentElement).getPropertyValue("--headerHeight");

console.log(headerHeight); // 60px

Resize Observer APIと組み合わせる

ヘッダーの高さを常に監視する(単一要素)

メニューの開閉などでヘッダーの高さが可変することを想定し、Resize Observer APIを使用して#headerを常に監視して、高さの変化があったら自動的に--headerHeightを更新する処理です。

index.js
const resizeTarget = document.getElementById("header");

if (resizeTarget) {
  const resizeObserver = new ResizeObserver((entries) => {
    // #headerは1つしかないので、entriesの1つ目を取得
    const entry = entries[0];

    if (entry.contentBoxSize) {
      const { blockSize } = entry.borderBoxSize[0];

      document.documentElement.style.setProperty(
        "--headerHeight",
        `${blockSize}px`
      );
    }
  });

  resizeObserver.observe(resizeTarget);
}

セクションの高さを常に監視する(複数要素)

アコーディオンの開閉などで高さが変わるセクションを監視する場合は、複数セクションあることを想定してquerySelectorAll()を使用すると良いでしょう。
その場合、

index.js
const resizeTargets = document.querySelectorAll(".section");

if (resizeTargets) {
  const resizeObserver = new ResizeObserver((entries) => {
    for (const entry of entries) {
      if (entry.contentBoxSize) {
        const { blockSize } = entry.borderBoxSize[0];

        entry.target.style.setProperty("--sectionHeight", `${blockSize}px`);
      }
    }
  });

  resizeTargets.forEach((target) => {
    resizeObserver.observe(target);
  });
}

参考・引用

この記事をシェアする