JavaScriptで要素の位置を取得する:getBoundingClientRect と offsetTop の違い

※本ブログの目的は個人の備忘録であり、コードは参考用として掲載しています。
実際に使用される際は、ご自身の環境で十分に動作確認を行ってください。
コードの利用によって生じたいかなる問題についても責任を負いかねますので、あらかじめご了承ください。

「特定の要素がページのどこにあるかを知りたい」

JavaScriptでそんなときに使われる代表的なプロパティがgetBoundingClientRect()offsetTop です。

どちらも「要素の位置を取得する」ためのものですが、実際には 測っている基準がまったく違う ため、目的に応じた使い分けが必要です。

要素の位置を取得するとは

まず、「位置を取得する」といっても、何に対しての位置を知りたいのかによって意味が変わります。

  • 親要素の中での位置を知りたいのか
  • ページ全体の中での位置を知りたいのか

この基準の違いが、getBoundingClientRect()offsetTop の使い分けを決める鍵になります。

offsetTop ― 親要素を基準にした位置

offsetTop「親要素(offsetParent)」から見た要素の上端の距離を返します。

const position = element.offsetTop;

つまり、「親の中でどのくらい下にあるか」を知るためのプロパティです。そのため、ページ全体とは関係ありません。

例えば、カードリストの中で「3番目のカードの位置を知りたい」など、コンテナ内での相対的なレイアウトを扱うときに便利です。

const parent = document.querySelector('.container');
const child = document.querySelector('.card');

console.log(child.offsetTop); // 親要素内での位置
  • スクロール量やページ全体の位置は関係なく、親要素の中での相対位置を取得できる。

getBoundingClientRect ― 画面上での位置

一方、getBoundingClientRect()ブラウザの表示領域(ビューポート) を基準にした位置情報を返します。

const rect = element.getBoundingClientRect();
console.log(rect.top); // 画面上端からの距離

この top の値は「現在の画面の上端からどれだけ離れているか」を表します。

つまり、ページをスクロールすれば値が変化します。

このままではページ全体の位置がわからないので、スクロール量(window.scrollY) を足すことで、「ページの最上部からの距離(絶対位置)」を求められます。

const absoluteTop = rect.top + window.scrollY;

スクロールで特定の要素まで移動させるとき、固定ヘッダーの高さを差し引くときなどに便利です。

const element = document.querySelector('.section');
const headerHeight = document.querySelector('header').offsetHeight;
const scrollToY = element.getBoundingClientRect().top + window.scrollY - headerHeight;

window.scrollTo({ top: scrollToY, behavior: 'smooth' });
  • ページ全体基準で位置を取得し、さらにヘッダー分を補正することで正確にスクロールできる。

使い分けについて

最初に述べた通り、ポイントは 「どこからの距離を測りたいか」 です。

目的

使うべきもの

説明

ページ全体の中での位置を知りたい

getBoundingClientRect().top + window.scrollY

スクロールを考慮した絶対的な位置がわかる

親要素の中での位置を知りたい

offsetTop

親要素からの相対的な位置を返す

まとめ

  • offsetTop → 親要素を基準にした相対位置
  • getBoundingClientRect().top + window.scrollY → ページ全体を基準にした絶対位置

要素の位置を取得するときは、「どこからの距離を測りたいのか?」を意識して選ぶことが大切です。

そうすることで、スクロール制御やアニメーションのずれを防ぎ、より安定した実装ができるようになります。