Skip to content

[기술 공유] CSS 3D

ocy1011 edited this page Nov 15, 2019 · 1 revision

7조 피키포키 기술 공유 WEEK2

기술 공유 주제

CSS 3D 속성

아래 예제 코드를 통해 생성되는 결과물

GIF

CSS 3D 필수 속성

perspective

  • perspective란 원근감을 뜻하는 단어이다. 자식 3d element들이 어떻게 보여질 지 정하는 필수 속성이다.
  • perspective가 0 또는 음수면 원근감이 적용되지 않는다.
  • 1px 이상의 값을 주었을 때 값이 커질수록 원근감이 작아진다.
  • 값이 너무 커지면 원근감이 느껴지지 않으니 적당한 크기로 조절하는 것이 중요하다.

transform-style

  • transform style이란 자식 요소들을 2D 공간에 배치할 것인지, 3D 공간에 배치할 것인지를 결정하는 속성이다.
  • 기본 속성은 flat으로 2D 공간에 위치 시키므로, 3D로 적용시키고 싶다면 preserve-3d로 바꾸도록 한다.

CSS 3D 핵심 속성

transform

  • transform이란 좌표공간을 변형하는 속성이다.
  • rotate를 통한 회전, scale을 통한 확대 및 축소, translate를 통한 이동

transform-origin

  • transform을 적용할 때 기준점을 정하는 속성이다.
  • 기본은 50% 50%로 center와 같다.

perspective-origin

  • 원근감의 기준점을 정하는 속성이다.
  • 기본은 50% 50%로 center와 같다.

예시 코드를 통해 이해하기

  • 아래 코드는 3D card를 만들고 회전시키는 코드이다.
  • html 파일에 아래의 코드를 넣고 실행시키면 화면에 2개의 card가 출력된다.
  • 왼쪽의 card는 keyframes animation을 통해 회전시킨다.
  • 오른쪽의 card는 transition을 통해 hover를 했을 때 회전시킨다.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <style>
      body {
        display: flex;
        margin: 0;
        width: 100vw;
        height: 100vh;
      }
      div#frame {
        display: flex;
        flex: 1;
        transform-style: preserve-3d;
        perspective: 500px;
        align-items: center;
        justify-content: center;
      }
      @keyframes rotate {
        from {
          transform: rotateY(0deg);
        }
        to {
          transform: rotateY(360deg);
        }
      }
      div.card {
        position: relative;
        width: 200px;
        height: 300px;
        border: 3px solid black;
        box-sizing: border-box;
        transform-style: preserve-3d;
        cursor: pointer;
        margin: 10px;
      }

      div.cardAnimation {
        animation-name: rotate;
        animation-duration: 5s;
        animation-iteration-count: infinite;
        animation-timing-function: linear;
      }
      div.cardTransition {
        transition: transform 1s;
      }

      div.cardTransition:hover {
        transform: rotateY(180deg);
      }
      div.cardFace {
        position: absolute;
        width: 100%;
        height: 100%;
        line-height: 300px;
        color: white;
        text-align: center;
        font-weight: bold;
        font-size: 40px;
        backface-visibility: hidden;
      }
      div.cardFront {
        background-color: red;
      }
      div.cardBack {
        transform: rotateY(180deg);
        background-color: blue;
      }
    </style>
    <div id="frame">
      <div class="card cardAnimation">
        <div class="cardFace cardFront">front</div>
        <div class="cardFace cardBack">back</div>
      </div>
      <div class="card cardTransition">
        <div class="cardFace cardFront">front</div>
        <div class="cardFace cardBack">back</div>
      </div>
    </div>
  </body>
</html>

frame

  • frame은 card 2개를 포함하는 공간이다.
  • transform-style: preserve-3d를 통해 자식 요소들이 3d공간에 위치하게 만들었다.
  • perspective: 500px를 통해 적당한 원금감을 부여하였다.
div#frame {
    display: flex;
    flex: 1;
    transform-style: preserve-3d;
    perspective: 500px;
    align-items: center;
    justify-content: center;
}

card

  • card에 transform-style: preserve-3d 속성을 적용하지 않으면 앞면과 뒷면 둘 중 하나만 보일 수 있다.
div.card {
    position: relative;
    width: 200px;
    height: 300px;
    border: 3px solid black;
    box-sizing: border-box;
    transform-style: preserve-3d;
    cursor: pointer;
    margin: 10px;
}

cardFace

  • backface-visibility: hidden;을 통해 현재 화면에서 보이지 않는 부분은 렌더링되지 않게 하고, 보이는 부분만 렌더링되게 한다.
  • transform: rotateY(180deg);를 통해 뒷면을 회전시켜 보이게 한다.
div.cardFace {
    position: absolute;
    width: 100%;
    height: 100%;
    line-height: 300px;
    color: white;
    text-align: center;
    font-weight: bold;
    font-size: 40px;
    backface-visibility: hidden;
}
div.cardFront {
    background-color: red;
}
div.cardBack {
    transform: rotateY(180deg);
    background-color: blue;
}

참고자료

Clone this wiki locally