Skip to main content

AspectRatio

주어진 aspect-ratio 비율을 맞춰주기 위해 선언적으로 사용하는 유틸 컴포넌트입니다.

미리 영역을 확보하여 Layout Shift를 방지하는데 효과적입니다.


다형성(polymorphism)

AspectRatio 컴포넌트는 다형성을 위해 as 속성을 지원합니다.

  • 기본적으로 div 태그로 자식 요소를 감싸서 렌더링하며, as 속성을 통해 감싸는 Wrapper 요소의 태그를 변경해 렌더링할 수 있습니다. (ex. div -> article)
  • 이때, 해당 Wrapper 요소에 aspect-ratio 속성을 적용해 영역을 확보합니다.

합성(Composition), 렌더링 위임(Rendering Delegation)

AspectRatio 컴포넌트는 asChild 속성을 통해 합성(Composition), 렌더링 위임(Rendering Delegation) 패턴을 지원합니다.

  • asChild 속성이 true라면 Slot 을 통해 자식 요소를 렌더링합니다.
  • 이때, 자식 요소에 aspect-ratio 속성을 적용해 영역을 확보합니다.
    • Slot은 자식으로 단일 요소만 허용됩니다.
    • Slot은 자식으로 컴포넌트가 올 경우 forwardRef, props를 허용해야 합니다. 허용하지 않으면 정상적으로 동작하지 않습니다.
    • asChild 속성을 사용 할 경우 Slot 문서를 참고해주세요.

Code

🔗 실제 구현 코드 확인

Interface

typescript
interface AspectRatioProps {
children: JSX.Element;
ratio: number;
asChild?: boolean;
style?: CSSProperties;
className?: string;
}
typescript
const AspectRatio: PolyForwardComponent<"div", AspectRatioProps, React.ElementType>

Usage

Default

  • 기본적으로 div 요소에 감싸지며 해당 divaspect-ratio 속성을 적용해 영역을 확보합니다.
typescript
import { AspectRatio } from '@modern-kit/react'

const Example = () => {
const imgUrl = 'https://github.com/user-attachments/assets/dd60ec12-afd7-44c9-bd6b-0069e16bf2c9';

return (
<div style={{ width: '500px' }}>
<AspectRatio ratio={427 / 640}>
<img src={imgUrl} />
</AspectRatio>
</div>
);
};

as

  • as 속성을 통해 감싸는 요소를 div가 아닌 특정 요소로 변경해 렌더링할 수 있으며, 해당 요소에 aspect-ratio 속성을 적용해 영역을 확보합니다.
typescript
import { AspectRatio } from '@modern-kit/react'

const Example = () => {
const imgUrl = 'https://github.com/user-attachments/assets/dd60ec12-afd7-44c9-bd6b-0069e16bf2c9';

return (
<div style={{ width: '500px' }}>
<AspectRatio as="article" ratio={427 / 640}>
<img src={imgUrl} />
</AspectRatio>
</div>
);
};

asChild

  • asChild 속성이 true라면 Slot 을 통해 자식 요소를 그대로 렌더링하고, 자식 요소에 aspect-ratio 속성을 적용해 영역을 확보합니다.
typescript
import { AspectRatio } from '@modern-kit/react'

const Example = () => {
const imgUrl = 'https://github.com/user-attachments/assets/dd60ec12-afd7-44c9-bd6b-0069e16bf2c9';

return (
<div style={{ width: '500px' }}>
<AspectRatio asChild ratio={427 / 640}>
<img src={imgUrl} style={{ width: '100%' }} />
</AspectRatio>
</div>
);
};

Example

Default


as article


asChild