ResizeObserver
Calls a function every time an observed element’s size changes, no matter the cause of the change.
- Returns
- A new
ResizeObserverobject.
Example
#const panel = document.querySelector('#panel')
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const border = Math.round(entry.borderBoxSize[0].inlineSize)
const content = Math.round(entry.contentRect.width)
console.log(`Panel: ${border} px, content: ${content} px`)
}
})
observer.observe(panel)The first notification reports the size right after observation starts. contentRect doesn’t include padding and the border, which is why it’s 26 px narrower. Drag the bottom-right corner of the panel in the preview, and the console will show each change.
Definition and usage
#ResizeObserver notifies you when a specific element’s size changes. The resize event on window only tells you about the window changing, but an element can change size for other reasons too: added content, a collapsed sidebar, or a class change. The observer catches every one of these cases.
The callback receives an array of ResizeObserverEntry objects. The contentRect field holds the width and height of the content area (without padding and border), while borderBoxSize and contentBoxSize give the sizes as arrays of objects with inlineSize (width, for regular horizontal text) and blockSize (height) fields.
If the element is displayed, the first call happens right after you start observing, so you learn the current size immediately. The observe() method adds an element, unobserve() removes it, and disconnect() ends the observation. The box option lets you choose which size to track, e.g. { box: "border-box" }.
Be careful about changing the observed element’s size directly inside the callback. The new size can’t be reported within the same frame, so the browser logs a "ResizeObserver loop completed with undelivered notifications" error, and the notification only arrives on the next frame. Put such changes off right away, e.g. with requestAnimationFrame().
Syntax
#new ResizeObserver(callback)
observer.observe(element)
observer.observe(element, { box })
observer.unobserve(element)
observer.disconnect()Parameters
#callback
function (entries, observer)
The function called after a size change. It receives an array ofResizeObserverEntryentries.box
optional, string (in observe())
Which size to track:"content-box"(default),"border-box", or"device-pixel-content-box".
More examples
#const card = document.querySelector('#card')
const nextWidths = ['300px', '200px']
const observer = new ResizeObserver(([entry]) => {
const width = Math.round(entry.borderBoxSize[0].inlineSize)
card.classList.toggle('wide', width >= 280)
console.log(`${width} px, wide layout: ${card.classList.contains('wide')}`)
const next = nextWidths.shift()
if (next) {
setTimeout(() => {
card.style.width = next
})
}
})
observer.observe(card)We change the width automatically here to show further notifications. Each change is put off with setTimeout(), because changing the size directly inside the callback would trigger a loop error. In a real app the size changes on its own, e.g. after collapsing a sidebar.
Browser support
#Widely available · since 2020
Works in all modern browsers, phones included. You can use it without worry.
- Chrome
- Edge
- Firefox
- Safari
Good practices
#- Reach for
ResizeObserverinstead of theresizeevent onwindowto react to an element’s size. An element can change size even while the window stays the same size. - Don’t change the observed element’s size directly inside the callback. Put the change off to the next frame, or only change things that don’t affect size, such as color.
- If you only need to adjust styles to a container’s width, consider CSS container queries (
@container). Then you don’t need JavaScript at all.
Related entries
#- IntersectionObserverWatches whether an element is visible within the window or a scrollable container, and calls a function whenever that changes.
- MutationObserverWatches for changes in the DOM tree: added and removed elements, attribute and text changes, and reports them in a single function.
- Element.getBoundingClientRect()Returns an element’s size and its position relative to the viewport, as a DOMRect object.
- requestAnimationFrame()Schedules a function to run right before the next screen repaint. Used for smooth animations driven by JavaScript.
- Element.classListAn object for adding, removing, toggling, and checking an element’s CSS classes.
Spotted a mistake or missing an example? Write to us.