Element. getBoundingClientRect()
Returns an element’s size and its position relative to the viewport, as a DOMRect object.
- Returns
- A
DOMRectobject with thex,y,width,height,top,right,bottom, andleftproperties (in CSS pixels).
Example
#const card = document.querySelector('#card')
requestAnimationFrame(() => {
const rect = card.getBoundingClientRect()
console.log(Math.round(rect.width), Math.round(rect.height))
console.log(Math.round(rect.left), Math.round(rect.top))
console.log(Math.round(rect.right), Math.round(rect.bottom))
})The width includes padding and the border, since the elements in the preview use box-sizing: border-box. left equal to 36 is 16 px of page spacing plus 20 px of the card’s margin, and right is always left + width. The measurement waits for the first frame (requestAnimationFrame()), since the example’s frame gets its size a moment after the script starts. On a normal, already-rendered page, you can measure right away.
Definition and usage
#The getBoundingClientRect() method measures an element the way it looks on screen. It returns a DOMRect object with width and height properties (size) and top, right, bottom, and left (edge positions). There are also x and y, which for elements equal left and top.
The position is measured relative to the visible window area (the viewport), not the start of the document. When you scroll the page down, the element’s top decreases, and it goes negative for elements above the screen. You get the position relative to the whole page by adding the scroll offset: rect.top + window.scrollY. position: fixed uses the same coordinates, so it’s easy to place something like a tooltip next to an element.
The size includes padding and the border, i.e. the whole area the element occupies. It also accounts for CSS transforms: transform: scale(2) doubles the returned width. Values can come out fractional, for example when the page is zoomed, so it’s worth rounding them before comparing. Reading it can also force the browser to immediately recompute the page layout if styles changed just before.
Syntax
#element.getBoundingClientRect()More examples
#const badge = document.querySelector('#badge')
requestAnimationFrame(() => {
console.log(badge.offsetWidth)
console.log(Math.round(badge.getBoundingClientRect().width))
})offsetWidth gives the width from the page layout and ignores transform. getBoundingClientRect() measures the element after scaling, i.e. the way it looks on screen.
const help = document.querySelector('#help')
const tooltip = document.querySelector('#tooltip')
help.addEventListener('click', () => {
const rect = help.getBoundingClientRect()
tooltip.style.left = `${Math.round(rect.left)}px`
tooltip.style.top = `${Math.round(rect.bottom + 8)}px`
tooltip.hidden = false
console.log(tooltip.style.left, tooltip.style.top)
})
requestAnimationFrame(() => help.click())The coordinates from getBoundingClientRect() and from position: fixed are measured from the same point, the top-left corner of the viewport. So the tooltip lands 8 px below the button’s bottom edge. We simulate the click on the first frame, once the preview’s frame already has its size.
Browser support
#Widely available
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- The coordinates change when you scroll, since they’re measured from the viewport. The position on the page is
rect.top + window.scrollY. - Round the results with
Math.round()before comparing or displaying them. Values can come out fractional when the page is zoomed. - An element hidden with
display: none, or not yet inserted into the document, has every dimension equal to 0. Measure it only once it’s displayed.
Related entries
#- Element.scrollIntoView()Scrolls the page and any scrollable containers so the element appears on screen, either instantly or smoothly.
- IntersectionObserverWatches whether an element is visible within the window or a scrollable container, and calls a function whenever that changes.
- ResizeObserverCalls a function every time an observed element’s size changes, no matter the cause of the change.
- getComputedStyle()Returns an element’s computed styles, meaning the CSS values the browser actually applied after taking every rule into account.
- Math.round()Rounds a number to the nearest integer.
Spotted a mistake or missing an example? Write to us.