친효스킨2 작업을 하면서 생각한게 아트북이니 엘범 컨샙이 물씬 느껴지면 좋겠다고 생각을 했습니다. 이제 커버 기능을 준비중인데 커버 스타일은 썸네일에 마우스를 올리면 뒤집히면서 제목과 내용, 글 작성 날짜 및 카테고리가 나왔으면 합니다. 그러기 위해서는 뭔가 3D같은 느낌을 주면 괜찮을 것 같았습니다. 그래서 만들었습니다. 3D 카드 느낌의 뒤집는 애니메이션 효과를 말입니다.
카드에 마우스를 올려보세요. 그러면 Y축으로 180도 돌아가면서 뒤집히는 애니메이션 효과가 연출됩니다. 신기하죠? 놀라운건 자바스크립트를 전혀 사용하지 않고 오로지 CSS 만으로 구성되었다는 부분입니다. 따라서 스크립트를 전혀 모르시는 분들도 어렵지 않게 3D 카드 뒤집기 효과를 만들 수 있습니다.
HTML 뼈대는 무척 간단합니다. 별거 없죠? 기준이 되는 카드 크기는 wrap 이라는 id 값을 가진 div입니다. 최상위 부모 요소죠. 그리고 핵심 카드는 card라는 클래스명을 가진 div입니다. 자식 요소에는 두 개의 div가 있고 각각 card-front와 card-back이라는 클래스명이 입력되어 있습니다. 제가 생각한 영역은 크게 두 개입니다. wrap과 card죠. 방금 말씀드렸듯 wrap은 카드의 기본 구조가 됩니다. 크기와 위치입니다. card안에는 두 개의 div가 있는데 각각 앞면과 뒷면을 담당합니다. 따라서 앞면과 뒷면을 이루는 div는 서로 겹쳐져 있어야 하며 card-back 클래스명의 div는 180도 뒤집힌 상태로 card-front 클래스명의 div와 겹쳐져야 합니다. 그래야 마우스를 올려서 돌릴 때 앞면이 돌아가면서 동시에 뒷면이 서서히 노출 될테니까요.
그림으로 다시 설명드리자면 위와 같은 경우입니다. 나머지 자세한 설명은 CSS 스타일을 살펴보면서 다시 말씀드리겠습니다.
CSS 스타일시트
전체 CSS 코드는 위의 미리보기에 있는 코드펜에 모두 마크업 되어있습니다. 본문에서는 부분 부분 코드별로 설명드리겠습니다.
먼저 이 부분입니다. card 클래스명의 div 부분입니다. 크기는 wrap에서 정의하고 있으니 전체 영역을 모두 사용하기 위해서 width, height 값은 100%로 되어있습니다. 즉 카드 크기를 변경하고 싶다면 #wrap의 가로/세로 크기를 변경하면 되는 것입니다. card 클래스명의 div가 실제로 보여지는 카드 영역이라는건 이미 말씀드렸습니다. 때문에 이곳에 애니메이션 효과가 연출됩니다. 그래서 transition을 넣어두었습니다. 다음은 이것입니다.
transform-style: preserve-3d;
이것은 3D 효과를 연출할 때 필수 코드라고 생각하시면 됩니다. 이게 입력되어 있어야 반대 영역의 오브젝트가 보여지는 효과를 연출할 수 있습니다.
#wrap:hover .card {
transform: rotateY(180deg);
}
다음은 이 부분입니다. 여기서 중요한 부분은 :hover입니다. 즉 마우스를 올렸을 때의 스타일을 정의하는 부분인데 핵심은 어떤 요소를 기준으로 할 것인가 입니다. 단순히 생각하면 card에 hover를 해주면 되지 않을까 싶습니다. card가 실제로 눈에 보여지는 부분이라고 말씀드렸던 것처럼 당연히 카드에 hover해야 할 것입니다. 하지만 실제로 card에 hover를 적용시키면 뭔가 동작이 이상하게 적용됩니다. 이유는 card가 돌아가면서 빈 공간이 생기고 마우스가 하필 그 빈 공간에 있으면 hover 효과가 더 이상 진행되지 않고 멈춰버리기 때문입니다. 그렇기에 마우스가 제대로 올라가야만 합니다. 그래서 저는 카드의 기준점이 되는 #wrap id값을 가진 div에 hover를 사용했습니다. 이 기준 영역은 절대로 변화하지 않는 요소이기에 hover가 무조건 정상 작동합니다.
다음은 transform 입니다. 트랜스폼은 포토샵에서 정말 많이 사용하는 기능 중 하나입니다. 오브젝트를 변형할 때 사용하는데 CSS에서도 이 트랜스폼 사용이 가능합니다. 트랜스폼에는 다양한 옵션이 있는데 여기에서는 rotate를 사용했습니다. rotate는 회전이라는 뜻입니다. 근데 자세히 살펴보면 Y가 추가로 입력되어 있습니다. 즉 rotateY라는건 오브젝트의 세로축인 Y축을 기준으로 괄호안의 값만큼 회전시킨다는 뜻입니다. 괄호 안에는 180deg가 입력되어 있으므로 시계 방향으로 180도 돌린다는 뜻이 됩니다. 만약 시계 반대 방향으로 돌리고 싶다면 음수인 -180deg를 입력하면 됩니다. 또한 Y축이 아닌 가로인 X축을 기준으로 카드를 뒤집고 싶다면 rotateX(180deg) 라고 사용하면 됩니다. 무슨 뜻인지 이해하셨으리라 생각됩니다.
다음은 card안에서 존재하는 앞면과 뒷면을 담당하는 각 div 자식요소에 대한 부분입니다. position: absolute를 사용한 이유는 이 두 개의 div를 완전히 겹쳐지게 만들기 위해서입니다. 또한 카드의 기준이 되는 #wrap id값을 가진 div와 완벽히 일치해야 하므로 top과 left를 모두 0으로 위치 정렬을 했습니다. 그래서 #wrap에는 position: relative가 입력되어 있는 것입니다.
display: flex를 사용한 이유는 텍스트를 카드의 중앙에 정렬하기 위해서입니다. 그래서 justify-content: center; 와 align-items: center;를 같이 사용한 것입니다. 따라서 이 옵션은 중앙정렬을 반드시 하지 않을 것이라면 굳이 사용하지 않아도 됩니다. 카드가 뒤집히는 3D 효과와는 무관한 옵션입니다.
backface-visibility: hidden;
여기에서의 핵심은 이 옵션입니다. 이것은 요소의 뒷면을 보이지 않게 만드는 것입니다. 반드시 필요한 핵심 코드입니다.
이제 마지막 설명입니다. 카드 앞면과 뒷면에 대한 스타일입니다. 크게 어려운 부분은 없습니다. 각 div에 백그라운드 색상을 넣어준 것 그리고 position: absolute;가 적용되어 있으니 레이어 개념을 심어주기 위해서 z-index 값이 각각 입력되어 있습니다. 앞면이 가장 위에 보여져야 하므로 card-font의 z-index 값이 card-back의 z-index 값보다 크면 됩니다.
그런데 card-back 클래스명의 div에만 transform: rotateY(180deg);가 혼자 입력되어 있습니다. 왜일까요? 이것도 되게 중요한 부분입니다. 이유는 위에서 보여드렸던 도식화에서 설명드렸습니다. 카드의 뒷부분은 뒤집힌 상태로 앞부분의 아래 부분에 위치한 상태가 기본값이기 때문입니다. 그래서 이미 180도가 뒤집힌 상태로 있어야 하기에 입력되어 있는 것입니다. 참고로 여기에 마크업된 180deg는 양수든 음수든 상관 없습니다. hover했을 때 card가 변화하는 것이지 card-back이 변화하는건 아니기 때문입니다. 여기에서는 뒷면인 card-back의 기본 스타일만 정의되어 있으면 됩니다. 끝.