Languages
[Edit]
EN

React - stretch element content to parent with css transform scale

10 points
Created by:
Marcin
19520

In this article, we would like to show how in React create a component that scales content (child element) to container size keeping the content aspect ratio.

That approach is useful when we want to scale some element that must have fixed size, e.g. Google Ads on mobile web browsers that must have fixed size. The code lets us set fixed content size that will be scaled to container component size with keeping content ratio - it solves fluid GPT Ads problem in a web browser.

iframe element scaled to container size
iframe element scaled to container size

Note: this article uses component from article that describes how to monitor component size - AutoSizer component. To see the article go to this link.

Practical example:

// ONLINE-RUNNER:browser;

// Uncomment next line during working with JSX Compiler:
// import React from 'react';
// import ReactDOM from 'react-dom';

const AutoSizer = React.memo(({ interval, children, ...other }) => {
	const reference = React.useRef();
	const [size, setSize] = React.useState();
	React.useEffect(() => {
      	let storedWidth = size?.width;
      	let storedHeight = size?.height;
      	const id = setInterval(() => {
          	const element = reference.current;
        	if (element) {
              	const width = element.offsetWidth;
                const height = element.offsetHeight;
              	if (width != storedWidth || height != storedHeight) {
                  	storedWidth = width;
                  	storedHeight = height;
                    setSize({ width, height });
                }
            }
        }, interval ?? 100);
      	return () => {
        	clearInterval(id);
        };
	}, [interval]);
	return (
	  <div ref={reference} {...other}>
        {size && children && children(size.width, size.height)}
	  </div>
	);
});

const ContentStretcher = ({sizerInterval, contentWidth, contentHeight, children, ...other}) => (
  <AutoSizer
    {...other}
    style={{
      ...other.style,
      position: 'relative',
      display: 'flex'
    }}
    interval={sizerInterval}
  >
    {(containerWidth, containerHeight) => {
  		const contentScale =
              containerHeight * contentWidth < containerWidth * contentHeight
        	? containerHeight / contentHeight
        	: containerWidth / contentWidth;
  		return (
          <div
            style={{
              position: 'absolute',
              left: '50%',
              top: '50%',
              transform: `translate(-50%, -50%) scale(${contentScale})`,
              transformOrigin: '50% 50%',
            }}
          >
            {children}
          </div>
        );
    }}
  </AutoSizer>
);

// Usage example:

// It will create iframe with dirask.com that will be scalled up to container
// with keeping content aspect ratio.

const DiraskFrame = ({containerWidth, containerHeight, contentWidth, contentHeight}) => (
  <ContentStretcher
    style={{
        background: '#e1e1e1',
        width: `${containerWidth}px`,
        height: `${containerHeight}px`
    }}
    contentWidth={contentWidth}
    contentHeight={contentHeight}
  >
    <iframe
      src="https://dirask.com/about"
      style={{
        border: 'none',
        width: `${contentWidth}px`,
        height: `${contentHeight}px`
      }}
    />
  </ContentStretcher>
);

const App = () => (
  <div>
    <DiraskFrame
      containerWidth={100}
      containerHeight={100}
      contentWidth={200}
      contentHeight={200}
    />
    <br />
    <DiraskFrame
      containerWidth={300}
      containerHeight={300}
      contentWidth={200}
      contentHeight={200}
    />
    <br />
    <DiraskFrame
      containerWidth={300}
      containerHeight={200}
      contentWidth={150}
      contentHeight={150}
    />
    <br />
    <DiraskFrame
      containerWidth={200}
      containerHeight={300}
      contentWidth={150}
      contentHeight={150}
    />
  </div>
);

const root = document.querySelector('#root');
ReactDOM.render(<App />, root );

ReactJS

React - stretch element content to parent (css transform scale)
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join