Skip to content

Latest commit

 

History

History
71 lines (51 loc) · 3.2 KB

boxSizes.md

File metadata and controls

71 lines (51 loc) · 3.2 KB

Observing vs. Consuming ResizeObserverSize

There is an important distinction between the boxSize you observe and the boxSize you pass to your breakpoints.

You can observe a boxSize on an element, and then respond to changes in another boxSize of that same element.

There might be cases where observing the same box you're matching breakpoints against is not desirable. This package supports observing and consuming different boxes on the same element.

What's happening under the hood?

Consider this example code and chain of events:

import { Observe, useBreakpoints } from '@envato/react-breakpoints';

const MyObservedElementComponent = () => (
  /* observed changes to `contentBoxSize` will update Observe's context */
  <Observe box='content-box'>
    {({ observedElementProps }) => (
      <div {...observedElementProps}>
        <ChildComponent />
      </div>
    )}
  </Observe>
);

const ChildComponent = () => {
  const options = {
    widths: {
      0: 'foo',
      1000: 'bar'
    },

    /* above widths are matched against `devicePixelContentBoxSize` */
    box: 'device-pixel-content-box'
  };

  const { widthMatch: label } = useBreakpoints(options);

  return <div className={label}>This element is currently within the {label} range.</div>;
};
  1. You start observing an element's contentBoxSize. <Observe> puts a ResizeObserverEntry on its context. This object contains all box sizes of the observed element.
  2. <ChildComponent> is aware of all of the element's box sizes via <Observe>'s context. You decide you want to apply your breakpoints using the devicePixelContentBoxSize information.
  3. A moment later, the element's contentBoxSize changes.
  4. <Observe> updates the ResizeObserverEntry on its context, and <ChildComponent> responds accordingly.
  5. Then, the element's borderBoxSize changes, but not its contentBoxSize (for example, when a CSS animation adds additional padding to an element).
  6. Because borderBoxSize is not observed, <Observe>'s context does not get updated, and therefore <ChildComponent> does not update.
  7. Finally, after a while longer, the element's devicePixelContentBoxSize changes.
  8. Even though <ChildComponent> uses this box's size, <Observe> is not observing changes on this box, and does not update its context to inform <ChildComponent>.

⚠️ Important

A change in one given boxSize does not always mean that the element's other boxSizes have also changed.

Consider the CSS box model:

CSS Box Model

When padding or border increase in thickness, the content's size will remain unaffected. If you are observing changes in contentBoxSize, those padding and border changes will not trigger any updates.

Similarly, let's say you have the following element:

<div style="box-sizing: border-box; width: 100px; padding: 10px;">...</div>

Then you change that element's padding to 0. If you are observing changes in this element's borderBoxSize, this padding change will not trigger any updates because the borderBoxSize did not change.