# .boundingBox

[browser](../../../..) ⟩ [DOM](../../..) ⟩ [type](../..) ⟩ [Element](..) ⟩ [boxes](../boxes) ⟩ [Element+boxes]() ⟩ .boundingBox

{% hint style="success" %}
a [**Rect**](../../../../../appendix/custom/class/rect) relative to [**viewport**](../../window/viewport).

* <mark style="color:yellow;">**size**</mark>: (may be <mark style="color:red;">**fractional**</mark>)
  * almost the same as [border](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](../../window/viewport "mention").

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

{% tabs %}
{% tab title="🗺️ 圖解" %}
:floppy\_disk: [](<> "mention"),  👉 [coordinates](../../../../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](../../../../concepts/coordinates "mention") of document / [viewport](../../window/viewport "mention") / container
* [elem.position](../+ext/elem.position "mention") - document [coordinates](../../../../concepts/coordinates "mention") of [..](.. "mention")
* will change while [scroll](../../window/scroll "mention")
* [position](../../../../../css/layout/position "mention")
* [border](border "mention")
{% endtab %}

{% tab title="⬇️ 應用" %}
* [elem.position](../+ext/elem.position "mention") - <mark style="color:yellow;">**document**</mark> [coordinates](../../../../concepts/coordinates "mention") of [..](.. "mention").
{% endtab %}

{% tab title="💈範例" %}
{% hint style="info" %}
* [elem.shownote](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="📘 手冊" %}
* [..](.. "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 %}
