본문 바로가기

HTML ⁄ CSS ⁄ JS

CSS - Transform, Transition, Animation, 3D

 

 

 

자바스크립트 없이 CSS 만으로 재밌는 효과를 줄 수 있는 4가지 효과를 알아보자.

 

 

 

1. CSS Transform

 

(왼쪽 그림) transform으로 scale을 2배로 설정한 경우                (오른쪽 그림) width, height를 2배로 설정한 경우

 

'변형'을 뜻하는 Tranform은 CSS3에서 처음 등장했고  width, height 등을 조정하는 방법보다 성능이 좋다. 나머지 박스에 영향을 미치지 않고, 기준점이 중앙에 있다는 점이 특징이다.

 

 

중앙으로 설정되어있는 기준점은 transform-origin으로 쉽게 바꿀 수 있다.

.box:hover {
  transform-origin: 0% 0%;  	/* 좌측 상단으로 기준점 변경하기 */
  transform-origin: left top;	/* (같은 효과) */

  transform-origin: 100% 100%;    /* 우측 하단으로 기준점 변경하기 */
  transform-origin: right bottom; /* (같은 효과) */
}

 

scale은 숫자만 넣어주면 되지만, rotate는 각도의 단위인 deg를 빼먹으면 안 된다.

.box:hover {
  transform: scale(1.5) rotate(45deg); /* 1.5배로 키우고 45도 회전하기 */
}

 

그냥 skew를 하면 좌우로, skewY를 하면 위아래로 비틀 수 있다.

.box:hover {
  transform: skew(30deg);	/* 좌우로 비틀기 */
  transform: skewY(30deg);	/* 위아래로 비틀기 */
}

 

translate는 이동을 가장 부드럽게 처리하는 방법 중 하나이다. x, y좌표를 한 줄에 쓸 수도 있고 따로따로 써줘도 된다. translate3d를 사용하면 하드웨어 가속(GPU)을 이용해서 더 부드럽게 처리할 수 있다. 

.box:hover {
  transform: translate3d(30px, 10px, 0);  /* 이동하기 */
  transform: translate3d(30%, 10%, 0);  
  transform: translate(30px, 10px);
  transform: translateX(30px);
  transform: translateY(10px);
}

 

 

2. CSS Transition

'전환'을 의미하는 Transition을 이용하면 Transform을 부드럽게 이어지도록 스타일링할 수 있다. 수치로 표현된 값들에 모두(?) 적용 가능하다. 예를 들어, 헥사값인 색상은 적용할 수 있고, width값이 auto인 경우 적용할 수 없다.

.box {
  transition: 1s;       /* 기본값은 ease. 가속이 있어서 더 자연스러움 */
  transition: 1s linear;/* 등속도라서 기계적인 느낌을 줌 */
  transition: 1s 2s;    /* 순서대로 duration, delay*/
}

크롬 개발자 도구에서 베지어 곡선을 커스터마이즈하면 색다른 효과를 줄 수도 있다. 베지어 곡선에서 x축은 진행시간, y축은 위치를 나타낸다. 튕겨져 나가듯 탄성 있는 느낌을 주려면 위쪽의 분홍색 점을 위로 끌어당겨서 y축 기준으로 곡선이 역행하는 구간을 만들어 주면 된다.

 

크롬 개발자도구에서 조정가능한 베지어곡선

 

 

 

3. CSS Animation

Animation키프레임을 지정할 수 있어 Transition보다 다양한 전환 효과와다이내믹한 구성이 가능하다.

@keyframes sample-ani {
  0% {
      transform: translate(0, 0);
      opacity: 0;
  }
  50% {
      transform: translate(300px, 0);
      background: yellow;
  }
  100% {
      transform: translate(400px, 500px);
      background: red;
  }
  /* 0%는 from으로, 100%는 to로 대체 가능함 */
}

.box {
	animation: my-animation 2s linear forwards 3 alternate;
    /* forwards는 애니메이션 끝난 시점에 시작 지점으로 돌아가지 않고 끝난 위치에 남아있도록 함 */
    /* 3 대신 infinite 넣을경우 무한반복 */
    /* alternate는 왔다리갔다리, reverse는 방향 반대로 */
}

.box:hover {
	animation-play-state: paused;
    /* paused일 경우 일시정지, 기본값은 running */
}

 

이미지 스프라이트와 함께 사용하면 frame by frame을 간단하게 구현할 수 있다. 투명도 조정이 용이한 png 형식의 이미지 스프라이트를 이용하면 배경과 경계선을 깔끔하게 관리할 수 있어 gif보다 선호된다.

@keyframes frame-by-frame {
  to {
  	background-position: -2550px 0;
  }
}
/* 픽셀값을 음수로 입력하면 왼쪽으로 움직임*/
/* 픽셀값을 양수로 입력하면 오른쪽으로 움직임*/

.rolling {
  width: 150px;
  height: 150px;
  /* 150px로 보여주려는 경우, 이미지를 300px로 준비하면 고해상도로 표현 가능 */
  
  background: url('images/image_sprite.png') no-repeat 0 0 / 150px auto;
  /* 0 0은 백그라운드 이미지의 위치 */
  /* 150px auto은 백그라운드 이미지 크기 */
  
  animation: frame-by-frame 1s infinite steps(17);
  /* step(17)은 전체 이동거리를 17단계에 탁,탁,탁 나누어서 움직이도록 함*/
  /* 이미지 스프라이트에 포함된 frame 수에 따라 설정 */
}

 

 

4. CSS 3D

transform에 perspective를 설정하면 z축을 활성화(?)시켜 더욱 입체적인 느낌을 줄 수 있다.

개별시점 적용                              단일시점 적용

 

요소 각각에 개별 시점을 적용해서 동일한 모양으로 만들고 싶다면 카드 본인 클래스에 perspective를 설정해준다.

 

.card {
	transform: perspective(400px) rotateY(-45deg);
}

 

단일 시점을 적용해서 전체적인 원근감을 완성시키고 싶다면 부모 클래스에서 perspective를 설정해준다.

 

.view {
	perspective: 400px;
}

.card {
	transform: rotateY(-45deg);
}

 

 

다음과 같이 div를 추가해서 hover 했을 때 카드를 제자리에서 뒤집는 효과를 더해줄 수 있다.

<div class="view">
  <div class="card">
    <div class="front">앞면입니다</div>
    <div class="back">뒷면입니다</div>
  </div>
</div>

 

.card {
	transform: perspective(400px) rotateY(0deg);  
	/* 0deg: 시각적 효과는 없더라도 브라우저에게 디폴트 값을 알려줄 수 있도록 명시 */
	transition: 0.5s;
	transform-style: preserve-3d; /* HTML 요소간 3D효과가 전달될 수 있도록 함. (IE지원X) */
}

.view:hover .card {
	transform: rotateY(180deg); /* 매끄러운 효과를 위해 부모 hover시 돌아가도록 설정 */
}

.front {
	z-index: 1;
	-webkit-backface-visibility: hidden; /* 사파리 호환 */
	backface-visibility: hidden; /* 뒷면이 보이지 않도록 함, 표준속성을 맨 마지막에 써주도록 함 */
}

.back {
	transform: rotateY(180deg);
	-webkit-backface-visibility: hidden;
	backface-visibility: hidden;
}

 

 

기준점을 바꾸면 문을 당겨 여는 듯한 효과를 줄 수 있다.

 

.card {
	transform-origin: left; /* 회전축을 중심에서 좌측으로 이동해줌 */
}

.back {
	transform: rotateY(-180deg); /* 뒤집어지는 방향을 반대로 해줌 */
}