IT일상

CSS로 카드 뒤집는 3D 애니메이션 만들기

  • 프론트엔드
Profile picture

Written by solo5star

2023. 4. 29. 23:06

웹에서 이런 애니메이션을 본 적 있을까요?

3D로 카드가 뒤집어지는 효과인데, CSS를 사용하면 간단하게 만들 수 있습니다.

핵심 키워드 빠르게 알아보기

카드를 뒤집는 데에 필요한 CSS 속성은 backface-visibility, transform: perspective, transform: rotateY 입니다.

  • backface-visibilityrotateY로 인해 180도 뒤집혔을 때 표시할 지 여부를 정하는 옵션입니다.
  • transform: perspective는 3D 입체 효과를 주기 위한 원근감 옵션입니다.
  • transform: rotateY는 Y축을 기준으로 회전하는 속성입니다.

기본 모양 만들기

<head>
  <style>
    .card {
      display: inline-block;
      color: white;
    }

    .card > * {
      width: 180px;
      height: 100px;
      padding: 12px;
      border-radius: 8px;
    }

    .card-front { background: linear-gradient(rgb(80, 67, 52), rgb(111, 93, 73)); }
    .card-back { background: linear-gradient(rgb(127, 106, 83), rgb(156, 132, 104)); }
  </style>
</head>

<body>
  <div class="card">
    <div class="card-front">국민카드</div>
    <div class="card-back">뒷면!!</div>
  </div>
</body>
2

먼저, 카드 앞면과 뒷면을 만듭니다.

뒤집기

 .card {
   display: inline-block;
   color: white;
+  transition: transform 0.3s;
+  transform: rotateY(0deg);
 }
 
+.card:hover {
+  transform: rotateY(180deg);
+}

마우스를 올렸을 때 뒤집힐 수 있도록 :hover에서 transform: rotateY(180deg) 를 줍니다. rotateYY축을 기준으로 회전하는 transform 속성입니다. 180도 만큼 회전하면 뒤집어지겠죠?

부드럽게 뒤집어질 수 있도록 transition 속성도 추가하였습니다. 0.3s 로 설정되어 있는데, 더 느리게 하려면 이걸 큰 값으로 하면 됩니다.

원근감 주기

근데 밋밋하게 회전되지 않습니까??

맞습니다. 3D 효과가 없는데, 3D 효과를 주려면 원근감을 줘야 합니다.

 .card {
   display: inline-block;
   color: white;
   transition: transform 0.3s;
-  transform: rotateY(0deg);
+  transform: perspective(800px) rotateY(0deg);
 }
 
 .card:hover {
-  transform: rotateY(180deg);
+  transform: perspective(800px) rotateY(180deg);
 }

transform: perspective 속성을 주었습니다. perspective는 원근감을 주는 속성으로, 괄호 안의 픽셀은 거리를 나타냅니다.

5 6

perspective값이 작으면 가까이서 보는 것 처럼, 값이 크면 멀리서 보는 것 처럼 보일 겁니다.

뒷 면 180도 회전 시켜 놓기

+.card-back {
+  background: linear-gradient(rgb(127, 106, 83), rgb(156, 132, 104));
+  transform: rotateY(180deg);
+}

뒷 면을 180도 회전시켜 놓습니다. .card가 회전되면 따라서 회전되므로 서로 반대면을 보여주는 식입니다.

backface 안보이게 하기

카드의 앞 면, 뒷 면에서 backfacerotateY(180deg)가 적용되었을 때의 면은 표시되지 않아야 합니다.

그래야 두 면을 겹쳤을 때 자연스럽게 동작하기 때문입니다.

 .card {
   display: inline-block;
   color: white;
   transition: transform 0.3s;
   transform: perspective(800px) rotateY(0deg);
+  transform-style: preserve-3d;
 }
 
 .card > * {
   width: 180px;
   height: 100px;
   padding: 12px;
   border-radius: 8px;
+  backface-visibility: hidden;
 }

backface-visibilityhidden으로 설정하면 rotateY(180deg) 되었을 때 보이지 않습니다. 즉 backface가 보이지 않게 합니다.

transform-stylepreserve-3d로 설정하면 부모의 3D 효과가 자식에도 적용되는데, 이것이 없으면 잘 동작하지 않습니다.

합치기

이제 두 면을 합칠 준비가 되었습니다.

 .card {
+  display: inline-grid;
   color: white;
   transition: transform 0.3s;
   transform: perspective(800px) rotateY(0deg);
   transform-style: preserve-3d;
 }
 
 .card > * {
+  grid-area: 1 / 1 / 1 / 1;
   width: 180px;
   height: 100px;
   padding: 12px;
   border-radius: 8px;
   backface-visibility: hidden;
 }

grid를 사용하여 두 면을 겹치게 표시되도록 하였습니다. 의도했던 대로 잘 동작하네요!

최종 소스코드

국민카드
뒷면!!
<head>
  <style>
    .card {
      display: inline-grid;
      color: white;
      transition: transform 0.3s;
      transform: perspective(800px) rotateY(0deg);
      transform-style: preserve-3d;
    }

    .card:hover {
      transform: perspective(800px) rotateY(180deg);
    }

    .card > * {
      grid-area: 1 / 1 / 1 / 1;
      width: 180px;
      height: 100px;
      padding: 12px;
      border-radius: 8px;
      backface-visibility: hidden;
    }

    .card-front {
      background: linear-gradient(rgb(80, 67, 52), rgb(111, 93, 73));
    }

    .card-back {
      background: linear-gradient(rgb(127, 106, 83), rgb(156, 132, 104));
      transform: rotateY(180deg);
    }
  </style>
</head>

<body>
  <div class="card">
    <div class="card-front">국민카드</div>
    <div class="card-back">뒷면!!</div>
  </div>
</body>

Profile picture

Written by solo5star

안녕하세요 👋 개발과 IT에 관심이 많은 solo5star입니다

  • GitHub
  • Baekjoon
  • solved.ac
  • about
© 2023, Built with Gatsby