export const Lookbook = () => {
const lookbooks = useAppSelector(selectAllLookbooks);
return (
<main>
<S.LookbookSection>
<h3 className='ir'>HOW ABOUT OOTD 룩북 리스트</h3>
<S.LookbooksList>
{lookbooks.map(({ id, banners, name }) => (
<li key={id}>
<Link to={`/lookbooks/${id}`}>
<ImgBox src={publicURL(banners[0].img)} alt='' ratio='150%' />
<S.LookbookName>{name}</S.LookbookName>
</Link>
</li>
))}
</S.LookbooksList>
</S.LookbookSection>
</main>
)
}
룩북 페이지에서 다음과 같이 모든 이미지가 같은 width와 height를 가지면서 반응형으로 만들려고 한다.
ImgBox
컴포넌트를 살펴보자.
// components/common/ImgBox/index.tsx
export const ImgBox = ({ src, alt, ratio }: ImgBoxProps) => {
return (
<S.ImgConatiner ratio={ratio}>
<S.Img src={src} alt={alt} />
</S.ImgConatiner>
)
}
// components/common/ImgBox/style.ts
import styled from 'styled-components';
type TImgContainer = {
ratio: string;
}
export const ImgConatiner = styled.div<TImgContainer>`
display: block;
padding-top: ${(props) => props.ratio};
position: relative;
overflow: hidden;
`
export const Img = styled.img`
width: 100%;
height: 100%;
position: absolute;
object-fit: cover;
top: 0;
left: 0;
`
다음처럼 img 요소에는 width: 100%
, height: 100%
를 준 것을 확인할 수 있다. 하지만 img 요소를 감싸고 있는 div
요소는 width가 없다...?
export const ImgConatiner = styled.div<TImgContainer>`
display: block;
padding-top: ${(props) => props.ratio};
position: relative;
overflow: hidden;
`
그래서 padding-top
, padding-bottom
에는 부모 요소의 넓이에 비례하는 속성이 있다.
예를 들어, 부모의 넓이(ImgContainer)가 1200px이라면 padding-top=50%
의 값은 600px이 되어 width와 height의 비율이 2: 1이 된다.
<ImgBox src={publicURL(banners[0].img)} alt='' ratio='150%' />
나는 다음과 같이 props로 ratio='150%'
을 주고 padding-top에 사용하면 아래 사진처럼 width와 height의 비율이 1:2로 반응하는 이미지 컴포넌트를 생성할 수 있다.
그리고 얻은 lighthouse에서의 Performance 86점.. 그래도 접근성은 96점으로 잘지켜서 작성하고 있는 것 같아 기분이 좋다!