오늘은 카드에 마우스를 올렸을때, 카드가 뒤집히는 애니메이션을 구현해보고자 합니다.
카드 3개를 만들기 위한 기본적인 html 뼈대 구조,
애니메이션을 구현하기 위한 사전 css 지식,
마지막으로 완성된 css 코드
이렇게 3개의 순서로 살펴보고자 합니다.
html 구조
최상위 컴포넌트 <section>
└ div class="card" 3개
└ 각 카드당 <p> 2개 (각각 앞 뒷면 담당)
└ <img> (카드 이미지 담당)
<body>
<h1>카드 뒤집기</h1>
<section>
<div class="card">
<p class="front">
<img src="../img/lion.png" alt="캐릭터" />
</p>
<p class="back">
<img src="../img/card1.png" alt="로고" />
</p>
</div>
<div class="card">
<p class="front">
<img src="../img/lion.png" alt="캐릭터" />
</p>
<p class="back">
<img src="../img/card2.png" alt="로고" />
</p>
</div>
<div class="card">
<p class="front">
<img src="../img/lion.png" alt="캐릭터" />
</p>
<p class="back">
<img src="../img/card3.png" alt="로고" />
</p>
</div>
</section>
</body>
구현하고자 하는 기능
카드를 뒤집는 애니메이션을 구현하기 위해
다음과 같이 3단계로 기능을 정리하였습니다.
1. 기본적으로는 카드 앞면(라이언 모양)이 보이게 하기
2. 마우스를 올려놨을때, 카드가 뒷장으로 뒤집히는 효과넣기.
마우스를 다시 카드 바깥으로 빼면, 카드가 다시 앞장으로 뒤집히기.
3. 카드가 뒤집히면서 카드 뒷장(html,css,js 사진) 보이게 하기
알아야할 css 지식
카드 뒤집는 애니메이션을 구현하기 위해서
반드시 알아야할 css 지식이 3~4가지 있습니다.
🔎0. z-index 속성
화면에 어느것이 더 먼저보일지 우선순위를 정해준다.
z-index를 따로 작성하지 않는 일반적인 상황에서,
모든요소는 z-index:0으로 전부 동일하다.
하지만, 요소들이 겹치는 상황이 발생할때
요소가 보이는 우선순위를 정해주고싶다면 z-index를 활용한다.
값이 클수록 더 위에보이는 특징이있다.
더 먼저 보이고 싶은 요소에 더 큰 z-index 값을 부여하면 된다.
그래서 보통, 상단 header나 메뉴바 같은 가장 최상위 요소에 z-index:9999 와 같은 값을 부여한다.
주의해야할 점은,
z-index 값을 연속하여 사용하지 않는다는 점이다.
연속하여 사용한다면 나중에 연속하는 두 요소 사이에 다른 요소를 끼워넣고 싶을때
z-index 값을 여러번 재조정해야한다.
이런 대참사(?)를 막기위해 요소끼리 z-index값은 적당한 값(10 정도)의 간격을 두고 부여한다.
우리의 카드 뒤집기 상황에서는
카드 앞면, 뒷면이 동일한 위치에 있는데
카드를 뒤집기 전에는 앞면이 보여야하므로
앞면에 z-index: 10 을 부여하였다.
🔎1. perspective 속성
transform을 적용할때 함께 자주 쓰인다.
멀리보이는 시각적 효과와 원근감을 담당한다.
따라서, transform과 함께쓰면, 애니메이션이 더 극적으로 보이는 효과가 생긴다.
일반적으로 값이 작을수록 극적으로 보인다고 하지만,
애니메이션(transform) 및 transition과 함께쓴다면 값이 커질수록 애니메이션이 더 극적으로 연출된다고 느꼈다.
사용법은, 애니메이션을 적용하고자하는 요소의 직계부모에 perspective를 주고,
적용 요소에 transform 애니메이션을 적용한다.
🔎2. backface-visibility 속성
사용자를 향해 요소를 돌렸을 때 요소의 뒷면이 보이는지 여부를 설정한다.
backface-visibility: visible;
default값은 'visible'이어서, 따로 'hidden'으로 설정하지 않으면
transform으로 요소를 뒤집었을 때 뒷면이 보인다.
🔎3. transform 속성
어쩌면 이게 가장 중요할듯 싶다.!!
애니메이션을 담당하는 본체이며,
요소에 회전, 크기 조절, 기울이기, 이동 효과를 부여할 수 있다.
transform은 CSS의 시각적 서식 모델의 좌표 공간을 변경한다.
transform 종류에는 translate, skew, rotate 등... 많은데
우리가 구현하고자 하는 카드 뒤집기 기능에는
rotateY() 가 해당된다. 왜일까?
rotate()에서 X,Y,Z 축을 설명하자면 다음과 같다.
rotateX(), rotateY(), rotateZ()는 각 축을 기준으로 회전한다.
rotateX()는, 가로축인 X 축을 기준으로 회전하므로
카드에 rotateX()를 적용하면 위아래로 뒤집히는 효과가 부여될 것이다.
우리가 구현하고자 하는 기능은,
카드가 가로로 뒤집히는 기능이므로
위 사진으로 보아 세로축으로 뒤집히는 효과인 rotateY()를 사용하면 된다.
rotate 관련 함수는 인자값으로 전부 degree를 사용한다.
-180deg, 0deg, 180deg 등 음수,0,양수값 전부 가능하다.
카드뒤집기에 rotateY() & backface-visibility 를 활용하기
그렇다면, 카드뒤집기에 transform: rotateY()를 어떻게 활용해야할까?
정답은 앞 뒷면 각각 각도를 다르게 하여 rotateY()를 부여하되,
앞 뒷면 둘다 backface-visibility : hidden 으로 처리한다.
앞면에서 뒷면으로 넘어가는 효과와
뒷면에서 앞면으로 넘어가는 효과는 정반대이므로
rotate()의 deg 값도 각각 앞, 뒷면 상태일때 정반대로 부여한다.
앞면 -> 뒷면으로 넘어갈때, 앞면은 -180도로 회전시킨다.
뒷면 -> 앞면으로 넘어갈때, 뒷면은 180도 -> 0도로 회전시킨다.
이렇게 회전시키는 이유는, 0도를 기준으로 서로 반대효과를 주기 위해서이다.
추가적으로 고려해야할 점은,
뒷면 -> 앞면 넘어갈때 뒷면 카드가 뒤집히지 않은 원래 카드 본모습이 보여야 하므로
카드를 뒤집기 전 평소 상태에서는 뒷면을 미리 180도로 뒤집어놔야 한다.
최종 CSS 코드
참고로, 이번에는 애니메이션을 부드럽게 보여주기 위해
transition: 0.5s 를 따로 부여하였습니다.
카드가 부드럽게 넘어가는 효과가 있습니다.
.card {
...
perspective: 500px; /* 카드가 더 실감나게 뒤집힘 */
}
.card > p {
...
backface-visibility: hidden;
transition: 0.5s;
}
.front {
z-index: 10;
background-image: url("---");
}
.back {
transform: rotateY(
180deg
); /* 뒷장이 보이지 않을땐 뒤집힌 상태여야, 나중에 정방향 모습으로 보임*/
}
/* 앞장은 0 -> -180도, 뒷장은 180 -> 0도 */
.card:hover .front {
transform: rotateY(-180deg);
}
.card:hover .back {
transform: rotateY(0);
}
완성본
기능을 구현하면서 얻은것들
애니메이션을 제대로 알기전까진,
카드뒤집기와 같은 저런 효과는 단순 동영상이나 gif인줄 알았데
카드 앞면, 뒷면을 겹쳐서 각각 회전의 각도를 반대로 부여하는 방식으로
카드를 뒤집는 효과를 낼 수 있다는 신박한 방식을 알아가였다.
꼭 이 효과를 카드 뿐만 아니라,
나중에 웹페이지를 만들때 카드 앞 / 뒷면을 각각 유의미한 활동으로 채워서
앞면엔 활동 이름, 뒷면엔 활동 사진
이런식으로 활동적인? interactive한? 페이지를 만들 수 있다는 생각이 들었다.
역시 완성된 결과를 보며, 시각적으로 보이는것도 중요하구나! 를 다시금 깨달았다.