Exploring the Resize Observer Proposal

By on June 4, 2018 12:02 pm

Resize Observer allows developers to receive notifications when the size of an element’s content rectangle changes. This helps manage a variety of application layout scenarios including responsive application layout, flexible layouts such as split panes, or dynamic changes in content within an element in a page.

This proposal is part of the Web Incubator Community Group Charter (WICG), a lightweight venue for proposing and discussing new web platform features. Analogous in the approach of TC39 for JavaScript, WICG considers proposals under GitHub repositories and encourages browser vendors to implement versions of the proposals before they get finalized as a recommendation or standard.

Without Resize Observer, changes to element sizes requires a significant engineering effort to track and manage changes to the layout. Resize Observer provides a primitive that makes it easy and performant to track and react to changes in size on any element.

Resize Observer API

The Resize Observer API is straightforward and consistent with other Observer APIs such as Intersection Observer. A ResizeObserver is an event handler that receives an array of DOM nodes that have changed based on this handler. Each entry in that array contains a contentRect attribute, on which it is possible to query the width, height, top, and left properties. On the ResizeObserver instance, the observe method is then called to register resize observation on one or more DOM elements. Entries also contain a target attribute similar to other DOM event handlers.

var observer = new ResizeObserver( resizeObserverEntries => {
	for (let entry of resizeObserverEntries) {
		const rect = entry.contentRect;
		console.log('Element:', entry.target);
		console.log(`Element size: ${rect.width}px x ${rect.height}px`);
		console.log(`Element padding: ${rect.top}px ; ${rect.left}px`);
	}
});

observer.observe(domElement);
observer.observe(anotherDomElement);

Resize Observer reports the contentRect of an element, the border box minus the padding. While Resize Observer provides both the dimensions of the contentRect and the padding, Resize Observer only watches for changes to the contentRect. The top and left properties on the contentRect correspond to the getComputedStyle values for paddingTop and paddingLeft.

Observations will fire events when a watched Element is inserted/removed from DOM, when the watched Element display gets set to none, and when observation starts if an Element has display, and the Element’s size is not 0,0.

Observations do not fire for non-replaced inline Elements or by CSS transforms.

unobserve(target) allows for the cancellation of a single single observe, and disconnect() removes all entries on a ResizeObserver instance and the instance itself.

Note that for HTML elements, contentRect is not the same as the bounding box returned by getBoundingClientRect.

For SVG elements, Resize Observer’s contentRect is the full dimensions of the bounding box. Note that top and left are always set to zero as SVG elements do not have padding as SVG does not follow the HTML box model.

Resize Observer has a mechanism to prevent infinite resize recursions by deferring some resize event reports to the next animation frame. The algorithms and event loop portions of the Resize Observer specification provide more information.

Current Browser Support and Usage

Native browser support recently landed in Chrome 64. Review the caniuse Resize Observer matrix for more information. There is a polyfill that may be used for browsers back to Internet Explorer 11. While not as performant as a native implementation, it allows developers to use this new API for all modern web applications.

To get the polyfill, install it via npm:

npm install resize-observer-polyfill --save-dev

And then include it within your application as an ES Module:

import * as ResizeObserver from 'resize-observer-polyfill';

Dojo 2

Dojo 2’s widget system supports the Resize Observer API out of the box!

import Resize from '@dojo/widget-core/meta/Resize';
import * as ResizeObserver from 'resize-observer-polyfill';

this.meta(Resize).get('text-input'); // text-input is a key for a virtual DOM Node.

The following is a complete Dojo 2 Resize Observer example via Code Sandbox, inspired by an example from the Svelte framework:

A more comprehensive Dojo 2 layout example with Resize Observer is also available, including the source code.


Next steps

Let's Talk! Logo

Do you need help creating your next high-performance app? Are you struggling to determine the right architecture for your next project? Contact us to discuss how we can help!

Support Logo

Get help from SitePen On-Demand Development, our fast and efficient solutions to JavaScript and TypeScript development problems of any size.

Comments