ZeeCoder / use-resize-observer

A React hook that allows you to use a ResizeObserver to measure an element's size.
MIT License
651 stars 42 forks source link

Support for <img/> elements using `object-fit` #106

Closed nathanielrindlaub closed 11 months ago

nathanielrindlaub commented 11 months ago

I am trying to use use-resize-observer to watch for changes to the rendered dimensions of an <img/> element that uses object-fit: contain, but it appears as though the returned width & height dimensions are that of that image's parent element, not the rendered image itself. Is this intended behavior? Some sample code is below:

import React, { useRef, useState } from "react";
import ReactDOM from "react-dom";
import useResizeObserver from "use-resize-observer";
import "./styles.css";
import image from '../public/deer-mouse.jpg';

const App = () => {
  const imgRef = useRef(null);
  const { width, height } = useResizeObserver({ ref: imgRef });

  return (
    <>
      <div className="measurement">
        imgRef size is:{" "}
        <b>
          {width}x{height}
        </b>
      </div>
      <div>
        <div className="box">
          <img ref={imgRef} style={{ width: '100%', height: '100%', objectFit: 'contain'}} src={image} />
        </div>
      </div>
    </>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ZeeCoder commented 11 months ago

It may be, this hook is a very thin wrapper around ResizeObserver. Have you tried using a native ResizeObserve instance to see if you're getting anything different from it compared to the hook?

Could you create a codesandbox where the difference in behaviour is showcased?

It can also depend on the browser, see this svg issue.

nathanielrindlaub commented 11 months ago

Hey @ZeeCoder - I just put together a codesandbox example and it appears as though ResizeObserver exhibits the same behavior.

I double checked against a couple different browsers and they all did the same thing.

ZeeCoder commented 11 months ago

Thanks for the codesandbox! I think I see now where the confusion is. While object fit changes the size of the image visibly, the element's size itself doesn't change, as you can see from the outline.

see this screenshot where I added a red border to the img element, and added a 20px margin around it so that the separation between it and the parent is clear: image

Basically the resize observer measures the box size correctly.

I'm no css wizard unfortunately, but there might be a different way to do this where the box size follows the img size as well.

You could also just measure the size of the parent with uRO, and cacluate the size of the contained image yourself with JS, since you're already measuring things.

nathanielrindlaub commented 11 months ago

Ah gotcha - thanks for looking into it! Yeah, for now I am just calculating the size of the contained image myself and it's working fine.

ZeeCoder commented 11 months ago

Glad I could help :muscle: