Skip to content

Resize Observer

<quiet-resize-observer> stable since 1.0

Resize observers watch child elements and dispatch an event when they resize.

The component uses a ResizeObserver to monitor the dimensions of its direct children. A quiet-resize event is dispatched for each observed element, once when the element is first observed and once every time the element is resized.

The component is styled with display: contents , allowing you to easily apply flex and grid layouts to the containing element without the component interfering.

<div id="resize__overview">
  <quiet-resize-observer>
    <div class="resizable">
      <div class="handle"></div>
    </div>
  </quiet-resize-observer>

  <div class="dimensions"></div>
</div>

<script>
  const container = document.getElementById('resize__overview');
  const resizeObserver = container.querySelector('quiet-resize-observer');
  
  /* Log the element's dimensions on resize */
  resizeObserver.addEventListener('quiet-resize', event => {
    const contentRect = event.detail.entry.contentRect;
    const width = Math.round(contentRect.width);
    const height = Math.round(contentRect.height);

    dimensions.innerHTML = `${width}px &times; ${height}px`;
  });

  /* The code below is just to make the example resizable */
  const resizable = container.querySelector('.resizable');
  const handle = container.querySelector('.handle');
  const dimensions = container.querySelector('.dimensions');
  let isResizing = false;
  let startX, startY, startWidth, startHeight;
  
  function startResize(event) {
    isResizing = true;
    startX = event.clientX;
    startY = event.clientY;
    startWidth = resizable.offsetWidth;
    startHeight = resizable.offsetHeight;
    document.addEventListener('pointermove', resize);
    document.addEventListener('pointerup', stopResize);
    handle.setPointerCapture(event.pointerId);
    event.preventDefault();
  }

  function resize(event) {
    if (!isResizing) return;
    const width = startWidth + (event.clientX - startX);
    const height = startHeight + (event.clientY - startY);
    
    resizable.style.width = `${width}px`;
    resizable.style.height = `${height}px`;
  }

  function stopResize(event) {
    if (!isResizing) return;
    isResizing = false;
    document.removeEventListener('pointermove', resize);
    document.removeEventListener('pointerup', stopResize);
    handle.releasePointerCapture(event.pointerId);
  }

  handle.addEventListener('pointerdown', startResize);  

  // Show initial dimensions
  dimensions.innerHTML = `${resizable.clientWidth}px &times; ${resizable.clientHeight}px`;
</script>

<style>
  #resize__overview {
    position: relative;
    height: 200px;

    .resizable {
      z-index: 2;
      position: relative;
      width: 100%;
      min-width: 50px;
      max-width: 100%;
      height: 100%;
      min-height: 50px;
      max-height: 200px;
      border: solid 2px var(--quiet-neutral-stroke-soft);
      border-radius: var(--quiet-border-radius);
    }
    
    .handle {
      position: absolute;
      bottom: calc(-0.75rem + 1px);
      right: calc(-0.75rem + 1px);
      width: 1.5rem;
      height: 1.5rem;
      background-color: var(--quiet-primary-fill-mid);
      border: solid 2px var(--quiet-silent);
      border-radius: 50%;
      cursor: nwse-resize;
      touch-action: none;
    }

    .dimensions {
      position: absolute;
      z-index: 1;
      top: calc(50% - 0.5lh);
      left: calc(50% - 100px);
      width: 200px;
      font-size: .9375em;
      pointer-events: none;
      text-align: center;
    }
  }
</style>

Remember that only direct children of the host element are observed. Nested elements will not trigger intersection events.

Example Jump to heading

Providing content Jump to heading

Slot one or more elements into the resize observer and listen for the quiet-resize event. The event includes event.detail.entry, which is a ResizeObserverEntry object that corresponds to the observed change.

In it's simplest form, a resize observer can be used like this.

<quiet-resize-observer>
  ...
</quiet-resize-observer>

<script>
  const resizeObserver = document.querySelector('quiet-resize-observer');

  // Listen for resizes
  resizeObserver.addEventListener('quiet-resize', event => {
    console.log(event.detail.entry); // ResizeObserverEntry
  });
</script>

Remember that only direct children of the host element are observed.

API Jump to heading

Importing Jump to heading

The autoloader is the recommended way to import components but, if you prefer to do it manually, the following code snippets will be helpful.

CDN npm

To manually import <quiet-resize-observer> from the CDN, use the following code.

import 'https://cdn.jsdelivr.net/npm/@quietui/quiet-browser@1.0.0/dist/components/resize-observer/resize-observer.js';

To manually import <quiet-resize-observer> from npm, use the following code.

import '@quietui/quiet/dist/components/resize-observer/resize-observer.js';

Slots Jump to heading

Resize Observer supports the following slots. Learn more about using slots

Name Description
(default) The elements to observe. All direct children of the host element are observed, but not nested elements.

Properties Jump to heading

Resize Observer has the following properties that can be set with corresponding attributes. In many cases, the attribute's name is the same as the property's name. If an attribute is different, it will be displayed after the property. Learn more about attributes and properties

Property / Attribute Description Reflects Type Default
disabled Disables the resize observer. boolean false
box Sets which box model the observer will observe changes to. 'content-box'
'border-box'
'device-pixel-content-box'
'content-box'

Events Jump to heading

Resize Observer dispatches the following custom events. You can listen to them the same way was native events. Learn more about custom events

Name Description
quiet-resize-observer Emitted when a slotted element is resized. Like ResizeObserver, this event is also dispatched when each element is first observed. The event.detail.entry property contains a ResizeObserverEntry with information about the element's dimensions.
Search this website Toggle dark mode Get the code on GitHub Follow @quietui.org on Bluesky Follow @quiet_ui on X

    No results found