* return 부분
import styled, { css } from 'styled-components';
<StProductListContainer>
{/*메뉴 map으로 뿌려주기*/}
{products &&
selectedCategory &&
products[selectedCategory]?.map(
({ name, imgSrc, subName, description }) => {
return (
<StProductBox key={name}>
<StProductImg src={imgSrc} alt="productID" />
<StProductName>{name}</StProductName>
<StProductOverlay>
<h1>{name}</h1>
<h3>{subName}</h3>
<hr />
<p>{description}</p>
</StProductOverlay>
</StProductBox>
);
}
)}
</StProductListContainer>
* styled-component
// 제품 카드 전체 리스트를 감싸는 컨테이너
const StProductListContainer = styled.div`
max-width: 100rem;
margin: auto;
display: grid;
align-items: center;
grid-template-columns: repeat(4, 1fr);
transition: all 0.3s;
overflow: hidden;
@media screen and (max-width: 60rem) {
grid-template-columns: repeat(3, 1fr);
}
@media screen and (max-width: 37.5rem) {
grid-template-columns: repeat(2, 1fr);
}
`;
------------------------------------------------------------------------------
1. 제품 카드 리스트 전체를 감싸주는 컨테이너에 display: grid를 먹여준다.
2. grid-template-columns 속성을 넣어 grid의 열(columns)에서의 배치 형태를 정의해준다.
-> 1fr 1fr 1fr 1fr = repeat(4, 1fr): 1:1:1:1 비율인 4개의 column을 만든다.
------------------------------------------------------------------------------
// 제품 사진과 이름이 들어갈 박스
const StProductBox = styled.li`
list-style-type: none;
width: 100%;
aspect-ratio: 3/4;
border: 0.1rem solid #f1f1f1;
border-radius: 0.5rem;
position: relative;
overflow: hidden;
@media screen and (max-width: 60rem) {
min-width: 13rem;
width: 100%;
}
@media screen and (max-width: 37.5rem) {
min-width: 13rem;
width: 100%;
}
`;
----------------------------------------------------------------
3. width는 100%로 맞춰 grid의 칸 하나마다 채워질 카드의 크기를 정해준다.
----------------------------------------------------------------
// 상품 카드 안에 들어갈 이미지
const StProductImg = styled.img`
width: 100%;
height: 100%;
display: block;
`;
// 상품 카드 안에 들어갈 이름
const StProductName = styled.h1`
width: 100%;
padding: 0 1rem;
font-size: 1.5rem;
display: block;
position: absolute;
text-align: center;
color: #071f60;
bottom: 5%;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`;
* return 부분
import styled, { css } from 'styled-components';
<StSelectCategoryContainer>
{categories.map((category) => {
return (
<StCategoryButton
to={`/products?category=${category}`}
$selectCategory={selectedCategory}
key={category}
value={category}
>
{category}
</StCategoryButton>
);
})}
</StSelectCategoryContainer>
* styled-component
// 카테고리 탭 전체 컨테이너
const StSelectCategoryContainer = styled.ul`
display: flex;
justify-content: center;
padding: 2rem;
margin-bottom: 3rem;
@media screen and (max-width: 37.5rem) {
display: flex;
flex-direction: column;
align-items: center;
padding: 0;
}
`;
// 카테고리 버튼
const StCategoryButton = styled(Link)`
width: 25rem;
min-height: 4rem;
padding: 0.5rem 2rem;
border: 0.1rem solid #f1f1f1;
border-radius: 0.5rem;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: 1.3rem;
transition: 0.3s;
letter-spacing: 3px;
&:hover {
background-color: #ffe800;
color: #071f60;
cursor: pointer;
}
@media screen and (max-width: 37.5rem) {
min-width: 13rem;
width: 80%;
}
/* 눌러지는 카테고리마다 조건부 css */
${(props) => {
if (props.$selectCategory === props.children) {
return css`
background-color: #ffe800;
color: #071f60;
`;
}
return css`
background-color: white;
color: #7483aa;
`;
/* 내려준 props를 ${ }로 가져와서 if문으로 조건을 걸어준다.
props로 내려준 selectCategory와 선택된 요소가 같다면
return css``(백틱)로 배경색과 글자색을 바꿔준다. */
}}
`;
* styled-component (return 부분은 grid 완성 코드의 return과 같다)
// 이미지 import 필수!
import small_logo from '../../assets/img/small_Logo.png';
// 호버 시 올라오는 상품 설명 박스
const StProductOverlay = styled.div`
width: 100%;
height: 100%;
border-radius: 0.5rem;
top: 0;
left: 0;
position: absolute;
background: #ffe800;
padding: 2rem;
display: flex;
flex-direction: column;
opacity: 0;
transition: all 0.5s;
transform: translateY(2.5rem);
& h1 {
font-size: 2.3rem;
margin: 2rem 0 1.3rem 0;
}
& h3 {
margin: 0 0 0.6rem 0.2rem;
}
& hr {
border-color: #071f60;
width: 100%;
}
& p {
font-size: 1.2rem;
line-height: 1.5;
}
&:hover {
opacity: 0.7;
transform: translateY(0rem);
cursor: url(${small_logo}) 5 5, default;
}
@media screen and (max-width: 37.5rem) {
padding-top: 0.5rem;
h1 {
font-size: 1.5rem;
margin-bottom: 0.25rem;
}
h3 {
font-size: 0.8rem;
}
p {
font-size: 1rem;
}
}
`;
사실 flex 속성으로도 웬만한 구현은 다 할 수 있어서 grid는 한 번도 써본 적이 없었는데, 이번 기회에 grid 속성도 사용하고 견문이 넓어졌다. props의 폭넓은 사용법과 커스텀 커서를 이용하여 좋은 결과물을 낼 수 있어 뿌듯했다.
Grid 속성: https://studiomeal.com/archives/533
props css: https://devbirdfeet.tistory.com/177
커스텀 커서: https://blog.webi.kr/34