All Articles

styled-components에서 hover 사용하기

2차 프로젝트로 Stayfolio 라는 WEB을 클론 진행을 하게됬다.
내가 맡은 여러가지 중 PICK 페이지를 진행하는데 PICK 페이지는 각각의 ITEM들이 존재하는 페이지다.
먼저 이 ITEM을 컴포넌트로 만들것이다.
ITEM을 보니 이미지가 들어가고 아이콘, 텍스트 그리고 애니메이션도 적용되어있다.

이 블로그의 주제는 애니메이션 적용에 대한 경험이다.
이번 프로젝트에서는 scss가 아닌 styled-components를 사용했다.
styled-components는 scss에 비해 css 적용하기 위한 종속관계를 그리기 힘들다.
scss는

.example {
  .test {

  }
}

위 처럼 나타낼 수 있지만

styled-components는

const example = styled.div``;
const test = styled.div``;

컴포넌트 내 return 부분에서 JSX 문법으로 작성을하는데

const CP = () => {
  return (
    <example>
      <test />
    </example>
  );
};

위처럼 한다.

위 예시는 너무나도 간단해서 불편함을 알기 힘들지만 scss는 scss파일에서 각 식별자로 우선 순위를 주고 종속 관계도
나타낼 수 있고 html 요소는 서로 동 떨어져있지만 식별자를 이용해서 스타일을 적용할 수 있다.
하지만 styled-components는 example ,test가 각각의 사용자 정의 태그고(html 태그 의미) html 구조에 맞게 종속 관계를 그리다 보니 html 요소가 서로 동 떨어져 있을때 스타일을 연걸해서 적용할 수 없는 한계가 있었다.

나에게 닥친 문제는 이미지 요소 그리고 이미지 요소와 겹쳐지는 또 다른 요소, 그리고 이 둘을 묶는 상위 요소가 존재하는데 둘을 묶는 상위 요소에 hover를 주고 hover 적용될 때 이미지에 scale transition 그리고 서로 겹쳐지는 각각의 요소에 opasity 속성, background-color: rgba() 속성 등을 적용해서 시각적인 변화를 보여내려 하는데, scss처럼 id 식별자나, className 식별자로 관계도를 그리고, 스타일 적용을 할 수 없다보니 styled-components에서 각각의 정의한 태그에 hover를 줬었는데.. 제대로 작동하지 않았다.
그래서 조금의 JavaScript적인 생각을 해서 둘을 묶고 있는 상위 요소의 태그를 변수로서 사용해서 변화를 줘야하는 각 태그에다가 상위 요소 태그를 변수로 주고 hover를 주니 제대로 작동했다.

<ItemImgWrap>
  <ItemImgContainer>
    <ItemImg src={img} />
  </ItemImgContainer>
  <ItemTextWrap>
    <ItemText>
      {" "}
      <Icon className="fas fa-search" />
      VIEW
    </ItemText>
  </ItemTextWrap>
</ItemImgWrap>
const ItemImgWrap = styled.div`
  position: relative;
  overflow: hidden;
`;
const ItemImgContainer = styled.div`
  width: 100%;
  overflow: hidden;
`;
const ItemImg = styled.img`
  width: 100%;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.4, 0.95);
  ${ItemImgWrap}:hover & {
    transform: scale(1.2, 1.2);
  }
`;
const ItemTextWrap = styled.div`
  position: absolute;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  bottom: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.5);
  text-align: center;
  opacity: 0;
  cursor: pointer;
  ${ItemImgWrap}:hover & {
    opacity: 1;
  }
`;

위 관계도를 보면 각각의 태그들은 사용자 정의 태그이다.(컴포넌트라 부름)
styled-components는 스타일 적용을 위 처럼 정의하다보니 종속 관계를 scss처럼 할 수 없다.
그래서 스타일 상속 및 종속은 정의 윗 부분에 있는 태그 관계도에서 이뤄진다.
그렇다고 스타일 종속관계를 위해.. 태그 관계도를 난장판으로 만들 수 없고 말이다..
그래서 ItemImg와 ItemTextWrap을 포함하고 있는 ItemImgWrap 컴포넌트를 각 컴포넌트에서 변수처럼 사용하고 :hover 적용했다.