[CSS] 마우스 오버시 이미지 부드럽게 변환시키기

김zunyange·2023년 7월 15일
2

HTML / CSS

목록 보기
16/16
post-thumbnail

상황 🔍

한 아이콘이 있다. 그 부분에 마우스를 갖다 댔을 때 아이콘이 다른 아이콘으로 변경되기를 원했다. 매우 간절.
나는 한 아이콘을 흰색 버전 / 검정 버전으로 이미지 2개를 저장하고, 흰 아이콘을 처음에 보여준 후 hover 했을 때 검정 아이콘으로 바뀌도록 코드를 짰다.
CSS로는 classname 로 스타일 주거나, 삼항연산자로 조건을 걸어주거나, 부모 요소와 자식 요소를 결합하며 > 기호 쓰는 등 .. 하면 되는데 Styled-component로는 어떻게 해야 할지 몰라서 검색을 했고 결과적으로 hover 했을 때 content 에 이미지 경로를 작성하면 된다고 한다.

  width: 50px;
  cursor: pointer;

  &:hover {
    content: url('images/icon/github-bk.png');
  }

이렇게 말이다!
그런데 나는 스무스하게 이미지가 변경되기를 원해서 transition 로 단순하게 꾸며주면 된다고 생각했는데 왜인지 계속 스타일이 안먹혔다. GPT에 물어보기도 하고 검색해서 나오는 웬만한 코드는 다 적용해보았는데 계속 안되었다.
Maybe.. 🤔 내가 판단한 이유는 이미지끼리 변환돼서인 것 같았다. 예를 들어 적용했었던 코드 중 몇몇을 보면 보면,

시도 1.

//JS
<a
href="https://github.com/zunyange"
target="_blank"
rel="noreferrer noopener"
>
  <S.GoToGithub src="/images/icon/github.png" alt="Github" />
</a>
//Styled-component

export const 부모 = styled.div`
  position: relative;
`;

export const GoToGithub = styled.img`
  width: 50px;
  cursor: pointer;
  position: absolute;
  top: 0px;
  left: 0px;
  opacity: 0;
  transition: opacity 0.5s linear;

  &:hover {
    content: url('images/icon/github-bk.png');
    opacity: 1;
  }
`;

부모에 relative 를 주고 top, left로 위치 지정 후(왜인지는 모르겠다), hover 전에 opacity 를 0으로 준다. 그리고 hover시에 opacity 를 1로 하여 이미지를 변경하는 과정에서 transition 이 적용될 것이다. 그런데 ,, 잘 되는 듯 싶지만 처음에 이미지가 아예 보이지가 않는다.
왜냐? opacity : 0 이니깐 ..
그래서 hover 전에도 opacity : 1 를 한다 해도 transition 이 적용되지 않고 뚝딱뚝딱 이미지가 바뀔 뿐이다 ..


시도 2.

//Styled-component
  export const GoToGithub = styled.img`
  width: 50px;
  cursor: pointer;
  transition: opacity 0.8s;

  &:hover {
    animation: fadeImage 1s;
  }

    @keyframes fadeImage {
    0% {
      opacity: 1;
    }
    50% {
      content: url('images/icon/github-bk.png');
      opacity: 0.5;
    }
    100% {
      content: url('images/icon/github-bk.png');
      opacity: 1;
    }
  }
`;

이 방법도 잘 되는 듯 싶지만 마우스를 잘 보면 마우스가 계속 hover 돼있다면 검정 아이콘에서 멈춰야 하는데 다시 원래 흰색 아이콘로 돌아오는 문제점이 있었다. 그 외에도 아래와 같은 수많은 방법을 시도해보았다.

시도 3.

  transition: all 0.5s ease;
  &:hover {
    content: url('images/github-bk.png');
  }

transition 안됨.

시도 4.

  transition: all 0.5s;
  &:hover {
    content: url('images/github-bk.png');
    transition: all 0.5s;
  }

transition 안됨22.

시도 5.

  transition: 1s ease;
  &:hover {
    content: url('images/github-bk.png');
    transition: 1s ease;
  }

transition 안됨33.
transition 을 어떻게 적느냐는 중요한 게 아니군!!

시도 6.

export const GoToGithub = styled.img`
  width: 50px;
  cursor: pointer;
  -webkit-transition: 0.5s ease-in-out;
  transition: 0.5s ease-in-out;
  &:hover {
    content: url('images/github-bk.png');
  }
`;
// OR
export const GoToGithub = styled.img`
  width: 50px;
  cursor: pointer;
  transition: 0.5s ease-in-out;
  &:hover {
    content: url('images/github-bk.png');
    -webkit-transition: 0.5s ease-in-out;
    transition: 0.5s ease-in-out;
  }
`;
// OR
export const GoToGithub = styled.img`
  width: 50px;
  cursor: pointer;
  -webkit-transition: 0.5s ease-in-out;
  transition: 0.5s ease-in-out;
  &:hover {
    content: url('images/github-bk.png');
    -webkit-transition: 0.5s ease-in-out;
    transition: 0.5s ease-in-out;
  }
`;

세 가지 모두 안된다. 😭

이렇게 하나하나씩 코드를 수정해가며 원인을 알아보려 했는데 성공한 결과물이 없어 이렇게 문제 해결 과정을 적어보려 한다..
반드시 해결해낸다는 마음으로 .. !! 내가 원하는 디자인 컨셉?이 있는데 뚝딱거리는 스타일보다는 부드럽게 영롱한😉 느낌을 주고 싶었기 때문이다.


다시 검색하면서 느낀게 있다.
사실 처음에 자바스크립트를 배운다면 css 혹은 sass 로 스타일 주는 것이 기본적이고, 검색을 할 때에도 Styled-component 보다는 css 방법이 대부분이다. 그런데 내가 왜 조건을 스타일드라고 부가적으로 검색하지 않고 무작정 "CSS 마우스 오버시 이미지 변환" 이라고 했을까?!
아직까지 뭔가 Styled-component가 완벽하게 100% 이해되지 않은 것도 있고, CSS 로 검색나온거 보고 활용해야지~ 응용해야지~ 라고 생각은 하지만 제대로 설명은 읽지 않고 코드만 일단 내놔!! 일단 복붙해보고 되면 공부해보자는 마음으로 서치를 했던 것 같다. 그래서인지 차근차근 다시 방법을 찾아보며, 리액트는 아니더라도 html & css 로 이미지 변환한 어떤 코드를 보고 아하! 느낀 점이 있다.
이 분의 설명으로는 "div 에 이미지를 2개 포개놓고 div 에 마우스 오버시 opacity:0; 을 줘서 위에 있는 이미지를 가려주는 식으로 처리하는게 가장 간단할듯 하다" 였다.
그러면 나도 hover했을 때 content 속성에 이미지 경로를 넣지 말고 처음부터 자바스크립트 파일에 이미지를 두개 넣으면 되겠네 !! 라는 생각이 번쩍 들었다.

오케이 해보겠숴.

1. img 태그 2개를 보여주고 숨기고 ‥

//js
<S.GoTo>
  <a
  href="https://github.com/zunyange"
  target="_blank"
  rel="noreferrer noopener">
    <S.GoToGithub src="/images/icon/github.png" alt="Github" />
    <S.GoToBlack src="/images/icon/github-bk.png" alt="Github" />
  </a>
</S.GoTo>
            
//Styled-component
export const GoToGithub = styled.img`
  width: 50px;
  cursor: pointer;
  transition: 1s;
  ${GoTo} :hover & {
    display: none;
  }
`;

export const GoToBlack = styled.img`
  width: 50px;
  display: none;
  ${GoTo} :hover & {
    display: block;
  }
`;

🛠 GoToGithub 태그에 마우스 오버시 opacity가 0으로 설정되고 점차 희미해지며 GoToBlack 태그의 display가 block 및 opacity가 1로 설정되고 점차 페이드 인되는 코드이다. 하지만 여전히 transition 이 안된다. ㅜ_ㅜ 기대했는데 너무 괴롭다.. 분명 방법이 있을텐데 😵

🛠 혹은 onMouseEnter onMouseLeave 프로퍼티를 사용하고 해당 프로퍼티에 state 값을 true / false 로 트리거를 만든 다음 조건부로 렌더링 시키고, 트랜지션을 주입하는 방법도 있다지만 잘 되지 않았다.

2. 이미지 변환은 아니지만 '검정'색으로 변환

//js
<a href="https://github.com/zunyange">
  <S.GoToGithub src="/images/icon/github.png" alt="Github" />
</a>

//Styled-component
export const GoToGithub = styled.img`
  cursor: pointer;
  transition: 1s;

  &:hover {
    filter: invert(100%);
  }
`;

filter 를 사용해서 색깔이나 대비, 블러처리, 그림자 등 이미지에 여러 효과를 줄 수 있다고 한다. 여기서 filter: invert(100%)는 내가 원하는대로 흰 아이콘에서 검은 아이콘으로 잘 바꼈고, 내가 처음 시도했던 content 이미지 경로가 없어서 transition 도 잘 동작한다!!
그렇게 기쁜 마음에 다른 이미지들도 똑같이 하려 했는데,.. 두번째 이미지는 이번엔 흰 아이콘에서 초록 아이콘이 되길 원했다 ...(Velog 로고)
filter 로 검정색 뿐만 아니라 원하는 색으로 언제든 변경이 가능하다고 알고 있어서 초록으로 바뀌는 코드인 filter: hue-rotate(160deg) 를 해보았는데 .. 다른 색으로 바뀌는 것도 아닌 hover를 해도 계속 흰 아이콘 그대로 였다. 그 외에도 수많은 시도와 gpt와의 대화를 했지만 실패가 거듭되어 지쳐버렸다. 커뮤니티에도 질문을 해보았는데 그나마 2번 방법이 최대 실적이다. 마침 처음 내 의도도 모든 흰 아이콘을 검정으로 바뀌게 하는 거였는데, Velog 나 Linkedin 같이 고유의 색깔이 있는 아이콘은 가시적으로도 의미가 잘 보일 것 같아 수정한 거였는데 다시 바꾸지 뭐 ^-^

최종 구현


늘 문제를 해결하는데 있어서 과정을 까먹지 않으려고 생각나는대로 말하려다 보니 (며칠을 걸쳐서 해결하고 있어서) 너무 횡설수설 말을 하는 것 같은데 결과적으로는 해결하는게 우선이니까 ..! 기록용 메모라고 생각하고 😝 이렇게라도 하다보면 점점 글 쓰는 능력도 점차 성장하지 않을까 싶다.
나중에라도 완벽한 해결책을 찾게 되면 돌아와야지! 🏃🏻‍♀️🏃🏻‍♀️🏃🏻‍♀️

profile
배움은 즐거워 ~(*ૂ❛ᴗ❛*ૂ)

0개의 댓글