Element.getBoundingClientRect()

Element.getBoundingClientRect() メソッドは、要素の寸法と、そのビューポートに対する相対位置に関する情報を返します。

構文

domRect = element.getBoundingClientRect();

返値は DOMRect オブジェクトで、(パディングと境界の幅を含む)要素全体が収まる最小の長方形です。left, top, right, bottom, x, y, width, height の各プロパティは、長方形の全体の位置と大きさをピクセル数で記述します。 widthheight 以外のプロパティは、ビューポートの左上を基準としています。

このメソッドが返す DOMRect オブジェクトの widthheight プロパティは、内容物の幅や高さだけでなく、 paddingborder-width も含まれます。標準的なボックスモデルでは、これは要素の width または height プロパティ + padding + border-width と同じになります。しかし、もし box-sizing: border-box が要素に設定されていれば、これは width または height と等しくなります。

返される値は、その要素に対して getClientRects() が返す矩形の和、つまり、その要素に関連する CSS の border-box と見なすことができます。

空のボーダーボックスは完全に無視されます。もし要素のボーダーボックスの全てが空である場合は、 widthheight が 0 で、 topleft は、要素に対する(コンテンツ順での)最初の CSS ボックスの左上である矩形を返します。

境界矩形を計算するときには、ビューポート領域(または他のスクロール可能な要素)のスクロール量が考慮されます。これは、スクロール位置が変更される度に(その値はビューポートの相対値であり、絶対値ではないため) 矩形の境界の辺 (top, right, bottom, left) が変更されることを意味しています。

もし文書の左上隅を基準とする境界矩形が必要な場合は、現在のスクロール位置から独立した境界矩形を取得する topleft プロパティに、現在のスクロール位置を加えるだけです(これらは window.scrollXwindow.scrollY で取得できます)。

ブラウザー間で互換性のある代替手段

高いブラウザー間の互換性を必要とするスクリプトでは、 window.scrollXwindow.scrollY の代わりに window.pageXOffset (en-US)window.pageYOffset (en-US) を使うことができます。これらのプロパティへのアクセスを使わない、次のようなスクリプトもあります。

// For scrollX
(((t = document.documentElement) || (t = document.body.parentNode))
  && typeof t.scrollLeft == 'number' ? t : document.body).scrollLeft
// For scrollY
(((t = document.documentElement) || (t = document.body.parentNode))
  && typeof t.scrollTop == 'number' ? t : document.body).scrollTop

基本

この単純な例では、単純な <div> 要素のクライアント矩形を表す DOMRect オブジェクトを取得し、その下にプロパティを出力しています。

<div></div>
div {
  width: 400px;
  height: 200px;
  padding: 20px;
  margin: 50px auto;
  background: purple;
}
let elem = document.querySelector('div');
let rect = elem.getBoundingClientRect();
for (var key in rect) {
  if(typeof rect[key] !== 'function') {
    let para = document.createElement('p');
    para.textContent  = `${ key } : ${ rect[key] }`;
    document.body.appendChild(para);
  }
}

なお、 width/heightwidth/height + padding と等しくなります。

また、x/left, y/top, right, bottom の値は、それぞれのケースで、ビューポートの関連する辺から要素のその側までの絶対的な距離に等しいことに注意してください。

スクロール

この例では、文書がスクロールされたときに、クライアント矩形の境界がどのように変化するかを示しています。

<div id="example"></div>
<div id="controls"></div>
div#example {
  width: 400px;
  height: 200px;
  padding: 20px;
  margin: 50px auto;
  background: purple;
}

body { padding-bottom: 1000px; }
p { margin: 0; }
function update() {
  const container = document.getElementById("controls");
  const elem = document.getElementById("example");
  const rect = elem.getBoundingClientRect();

  container.innerHTML = '';
  for (let key in rect) {
    if(typeof rect[key] !== 'function') {
      let para = document.createElement('p');
      para.textContent  = `${ key } : ${ rect[key] }`;
      container.appendChild(para);
    }
  }
}

document.addEventListener('scroll', update);
update();

仕様書

Specification
CSSOM View Module
# dom-element-getboundingclientrect

メモ

最近のブラウザーでは返された DOMRect オブジェクトを変更することが可能ですが、これは DOMRectReadOnly を返す古いバージョンには該当しません。IE と Edge では、返された ClientRect オブジェクトに対し、見過ごされたプロパティを追加することができず、xy を補填することができません。

互換性問題 (下記参照) のため、 left, top, right, bottom のみに頼ることが最も安全です。

返された DOMRect オブジェクトのプロパティは、自身のプロパティではありません。in 演算子や for...in では返されたプロパティを見つけますが、他の Object.keys() のような API では失敗します。さらに予期しないことに、 Object.assign() のような ES2015 やより新しい機能では、返されるプロパティのコピーに失敗します。

rect = elt.getBoundingClientRect()
// emptyObj の結果は {}
emptyObj = Object.assign({}, rect)
emptyObj = { ...rect }
{width, ...emptyObj} = rect

DOMRecttop, left, right, bottom の各プロパティは他のプロパティ値から計算されます。

ブラウザーの互換性

BCD tables only load in the browser

関連情報