# .boundingBox

[browser](https://lochiwei.gitbook.io/web/browser) ⟩ [DOM](https://lochiwei.gitbook.io/web/browser/dom) ⟩ [type](https://lochiwei.gitbook.io/web/browser/dom/type) ⟩ [Element](https://lochiwei.gitbook.io/web/browser/dom/type/element) ⟩ [boxes](https://lochiwei.gitbook.io/web/browser/dom/type/element/boxes) ⟩ [Element+boxes](https://lochiwei.gitbook.io/web/browser/dom/type/element/+boxes) ⟩ .boundingBox

{% hint style="success" %}
a [**Rect**](https://lochiwei.gitbook.io/web/appendix/custom/class/rect) relative to [**viewport**](https://lochiwei.gitbook.io/web/browser/dom/type/window/viewport).

* <mark style="color:yellow;">**size**</mark>: (may be <mark style="color:red;">**fractional**</mark>)
  * almost the same as [border](https://lochiwei.gitbook.io/web/browser/dom/type/element/+boxes/border "mention") size (<mark style="color:green;">**integer**</mark>-valued).
  * "[box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing): border-box"\ <mark style="color:orange;">**size**</mark> =  ([width](https://developer.mozilla.org/en-US/docs/Web/CSS/width), [height](https://developer.mozilla.org/en-US/docs/Web/CSS/height)) -> padding/border included.
  * <mark style="color:yellow;">**standard box model**</mark>： \ <mark style="color:orange;">**size**</mark> = content([width](https://developer.mozilla.org/en-US/docs/Web/CSS/width), [height](https://developer.mozilla.org/en-US/docs/Web/CSS/height)) + padding + border.&#x20;
* <mark style="color:yellow;">**position**</mark>: ([.x](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/x), [.y](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/y)) or ([.left](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/left), [.top](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/top)) relative to [viewport](https://lochiwei.gitbook.io/web/browser/dom/type/window/viewport "mention").

:point\_right: compare： [border](https://lochiwei.gitbook.io/web/browser/dom/type/element/+boxes/border "mention") (a [**Rect**](https://lochiwei.gitbook.io/web/appendix/custom/class/rect) relative to .[offsetParent](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent))
{% endhint %}

{% tabs %}
{% tab title="🗺️ 圖解" %}
:floppy\_disk: [](https://lochiwei.gitbook.io/web/browser/dom/type/element/+boxes "mention"),  👉 [coordinates](https://lochiwei.gitbook.io/web/browser/concepts/coordinates "mention")

<img src="https://2527454625-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MfvEFZnSBhKT6fJmus0%2Fuploads%2Ftv1sRBRIz5H3hbD1mAVB%2Fbounding.box.svg?alt=media&#x26;token=036a53bd-1bd3-45b5-b259-915ff1e03221" alt="&#x22;elem.boundingBox&#x22; is a Rect relative to viewport" class="gitbook-drawing">
{% endtab %}

{% tab title="🧨 雷區" %}
{% hint style="danger" %}
the elements <mark style="color:red;">**must**</mark>**&#x20;**<mark style="color:yellow;">**be in the document**</mark> to read [offsetHeight](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight) and **other properties**, a <mark style="color:orange;">**hidden**</mark> (<mark style="color:blue;">`display:none`</mark>) or <mark style="color:red;">**out of the document**</mark> element has <mark style="color:red;">**no size**</mark>.
{% endhint %}

{% hint style="danger" %} <mark style="color:yellow;">**coordinates**</mark> [right](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/right)/[bottom](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/bottom) are <mark style="color:red;">**different**</mark> from <mark style="color:yellow;">**CSS**</mark> <mark style="color:purple;">right</mark>/<mark style="color:purple;">bottom</mark> <mark style="color:yellow;">**properties**</mark>, in CSS,&#x20;

* **right**: the distance <mark style="color:yellow;">**from the**</mark>**&#x20;**<mark style="color:red;">**right**</mark>**&#x20;**<mark style="color:yellow;">**edge**</mark>.&#x20;
* **bottom**: the distance <mark style="color:yellow;">**from the**</mark>**&#x20;**<mark style="color:red;">**bottom**</mark>**&#x20;**<mark style="color:yellow;">**edge**</mark>.
  {% endhint %}
  {% endtab %}

{% tab title="⭐️ 重點" %}
{% hint style="warning" %} <mark style="color:red;">**inline elements**</mark> (such as <mark style="color:blue;">\<span></mark>, <mark style="color:blue;">\<code></mark>, <mark style="color:blue;">\<b></mark>)&#x20;

* may span <mark style="color:yellow;">**multiple lines**</mark> and consist of <mark style="color:yellow;">**multiple rectangles**</mark>.
* the bounding rect returned by [.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) will include the <mark style="color:red;">**entire**</mark> width/height of these lines.
* call [.getClientRects()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects) to get individual rectangles of <mark style="color:yellow;">**inline**</mark> elements.
  {% endhint %}
  {% endtab %}

{% tab title="👥 相關" %}

* [coordinates](https://lochiwei.gitbook.io/web/browser/concepts/coordinates "mention") of document / [viewport](https://lochiwei.gitbook.io/web/browser/dom/type/window/viewport "mention") / container
* [elem.position](https://lochiwei.gitbook.io/web/browser/dom/type/element/+ext/elem.position "mention") - document [coordinates](https://lochiwei.gitbook.io/web/browser/concepts/coordinates "mention") of [..](https://lochiwei.gitbook.io/web/browser/dom/type/element "mention")
* will change while [scroll](https://lochiwei.gitbook.io/web/browser/dom/type/window/scroll "mention")
* [position](https://lochiwei.gitbook.io/web/css/layout/position "mention")
* [border](https://lochiwei.gitbook.io/web/browser/dom/type/element/+boxes/border "mention")
  {% endtab %}

{% tab title="⬇️ 應用" %}

* [elem.position](https://lochiwei.gitbook.io/web/browser/dom/type/element/+ext/elem.position "mention") - <mark style="color:yellow;">**document**</mark> [coordinates](https://lochiwei.gitbook.io/web/browser/concepts/coordinates "mention") of [..](https://lochiwei.gitbook.io/web/browser/dom/type/element "mention").
  {% endtab %}

{% tab title="💈範例" %}
{% hint style="info" %}

* [elem.shownote](https://lochiwei.gitbook.io/web/browser/dom/type/element/+boxes/bounding/elem.shownote "mention") - show note beside element.
  {% endhint %}

:floppy\_disk: replit: [elem.getBoundingClientRect()](https://replit.com/@pegasusroe/elemgetBoundingClientRect#script.js)

```javascript
const { log } = console;

// ⭐️ $all(): select all element
function $all(selector, parent = document) {
    return parent.querySelectorAll(selector);
}

// 🔸 elem.showMessageUnder()
Element.prototype.showMessageUnder = function(html, {
    timeout = 5,
    showRectInfo = true,
}={}) {

    // ⭐️ bounding rect 
    let rect = this.getBoundingClientRect();    
    log(rect);

    // create <div> element
    let div = document.createElement('div');
    
    // better to use a css class for the style here (⭐️ don't forget "px"!)
    div.style.cssText = `position: fixed; color: red; background: lightyellow; left: ${rect.left}px; top: ${rect.bottom}px; padding: 4px; border: solid black 1px; opacity: 0.7`;

    if (showRectInfo) {
        html += `<br><code>{x: ${rect.x.toFixed(0)}, y: ${rect.y.toFixed(0)}, width: ${rect.width.toFixed(0)}, height: ${rect.height.toFixed(0)}}</code>`;
    }

    div.innerHTML = html;
    document.body.append(div);        // add to the DOM tree
    
    if (timeout > 0) {
        setTimeout(() => div.remove(), timeout * 1000);    // remove from DOM
    }

    return div;
};


// click handler
document.onclick = (event) => {

    const tag = event.target.tagName;

    if (tag !== 'BUTTON') {
        log(`clicked on a <${tag}>`); return;
    }

    $all('span').forEach(span => {
        span.showMessageUnder(`bounding rect:`);    // 🔸 custom method
    });
};
```

{% endtab %}

{% tab title="📗 參考" %}

* [ ] JavaScript: The Definitive Guide (15.5 Document Geometry & Scrolling)
  {% endtab %}

{% tab title="📘 手冊" %}

* [..](https://lochiwei.gitbook.io/web/browser/dom/type/element "mention") ⟩&#x20;
  * [.getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect)
  * [.getClientRects()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getClientRects) - individual rectangles of <mark style="color:yellow;">**inline**</mark> elements.
* [DOMRectReadOnly](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly) ⟩[ ](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/right)
  * [DOMRect](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) (<mark style="color:red;">**NOT**</mark>**&#x20;**<mark style="color:yellow;">**read-only**</mark>) ⟩ ([.x](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/x), [.y](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/y))&#x20;
    * [.right](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/right), [.bottom](https://developer.mozilla.org/en-US/docs/Web/API/DOMRectReadOnly/bottom)
* [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing)
  {% endtab %}
  {% endtabs %}
