Ratio를 유지하는 이미지 컴포넌트
화면의 크기에 따라서 가로, 세로 비율을 유지하는 이미지 컴포넌트를 어떻게 만들 수 있을까? 결론은 position: "absolute"과 padding-bottom을 이용하는 것이다. 하지만, 한번에 코드가 이해가 가지 않아서 작게 쪼개어 이해해보았다.
먼저, 아래의 코드는 <div> 안에 <img>를 배치하는 아주 기본적인 코드이다. 이 코드는 단순히 브라우저에 원본 이미지와 orange 색의 부모를 함께 보여줄 것이다.
export default function App() {
return (
<div style={{ backgroundColor: "orange" }}>
<img
src="https://picsum.photos/200/300"
/>
</div>
);
}

다음 코드는 <img>에 width, height 100%를 주었다. 이때, <div>는 default 값으로 width 100%와 컨텐츠 크기의 height를 가지기 때문에 이미지가 전체 width와 height를 가지며 밑으로 스크롤이 더 생긴 것을 확인할 수 있다.
export default function App() {
return (
<div style={{ backgroundColor: "orange" }}>
<img
src="https://picsum.photos/200/300"
style={{ width: "100%", height: "100%" }}
/>
</div>
);
}

위의 코드에 더해, 부모인 <div>에 paddingBottom 값을 주었다. paddingBottom은 부모인 <div> width의 25%만큼 추가가 된 것이다. 그래서 paddingBottom: "25%"라는 것은 4:1의 ratio을 가질 수 있겠다.
여기서 주의할 점은, <div>의 높이는 <img>의 원래 높이 + paddingBottom의 값이라는 것이다. 즉, <div>의 높이는 컨텐츠의 크기에 더해 추가적인 paddingBottom 값이 생기게 되는 것이다. 여기까지 봐서는 어떻게 paddingBottom 값으로 ratio을 유지하겠다는건지 잘 모르겠다.
export default function App() {
return (
<div style={{ backgroundColor: "orange", paddingBottom: "25%" }}>
<img
src="https://picsum.photos/200/300"
style={{ width: "100%", height: "100%" }}
/>
</div>
);
}
하지만, 마지막 단계인 아래의 코드를 보면 이해가 가기 시작한다. position을 설정해 주는 것이다. <img>의 position: "absolute"으로 설정하면, <div>의 높이를 내부 컨텐츠가 아닌 paddingBottom 값만이 결정하게 되고, <img>는 <div> 크기에 맞춰지게 된다. 처음에는 잘 이해가 가지 않을 수 있는데, absolute 요소는 static과 다르게 부모의 컨텐츠 크기에 영향을 주지 않는 독립적인 요소로 변한다는 개념을 이해하면 도움이 된다. 그래서 최종 코드는 다음과 같다. 여기서 paddingBottom 값을 자유롭게 조정하면 이미지 크기와 비율이 함께 변하는 것을 확인할 수 있다.
export default function App() {
return (
<div
style={{
backgroundColor: "orange",
position: "relative",
paddingBottom: "25%",
}}
>
<img
src="https://picsum.photos/200/300"
style={{ width: "100%", height: "100%", position: "absolute" }}
/>
</div>
);
}
