본문 바로가기
dev/javascript

[javascript] CSS transition 애니메이션 (타이밍 함수)

by 최연탄 2022. 11. 25.
728x90
반응형

참고: https://zellwk.com/blog/css-transitions/

HTML 구성요소를 애니메이션화하는 가장 간단한 방법은 CSS transition을 사용하는 것 입니다. 이 포스트에서는 CSS transition이 어떻게 작동하는지, 또 이를 활용해 어떻게 애니메이션을 만드는지를 알아보겠습니다.

transition은 CSS 속성이 일정한 기간동안 하나의 값에서 다른 값으로 변경될 때 발생합니다.

다음의 예와 같이 transition 속성을 사용하여 CSS transition을 생성할 수 있습니다:

.selector {
  transition: property duration transition-timing-function delay;
}

transition 속성은 transition-property, transition-duration, transition-timing-function, transition-delay의 4가지 CSS 속성의 약어로 구성되어 있습니다.

.selector {
  transition-property: property;
  transition-duration: duration;
  transition-timing-function: timing-function;
  transition-delay: delay

  /* 위 4개 속성의 약자 */
  transition: property duration timing-function delay;
}

transition-property는 transition을 걸 CSS 속성의 이름을 나타냅니다.

transition-duration은 transition이 지속될 시간을 나타냅니다. transition이 얼마나 지속되기를 원하느냐에 따라 숫자에 s를 붙여(예: 3s, 500ms) 사용합니다.

transition-timing-function은 transition이 발생하는 방식을 나타냅니다. linear나 ease 등을 선택할 수 있고 이는 뒤에 자세히 다룰 것 입니다.

transition-delay는 transition을 시작하기 전에 얼마나 대기할지를 나타냅니다. 이 값도 duration과 마찬가지로 s나 ms를 붙여 시간을 지정합니다.

transition 시작하기

CSS transition은 :hover(마우스가 HTML 요소 위로 올라갔을 때), :focus(사용자가 HTML 요소를 탭하거나 클릭했을 때), :active(사용자가 요소를 클릭했을 때) 와 같은 수도 클래스(pseudo class)로 직접 실행할 수 있습니다.

.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button:hover {
  background-color: #1ce;
}

See the Pen Untitled by shinyks (@shinyks) on CodePen.

또한 자바스크립트로 클래스를 추가하거나 삭제하여 CSS transition을 시작할 수 있습니다.

.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button.is-active {
  background-color: #1ce;
}
const button = document.querySelector('.button');

button.addEventListener('click', () => button.classList.toggle('is-active'));

See the Pen transition click by shinyks (@shinyks) on CodePen.

transition-timing-function 이해하기

transition-timing-function는 transition이 어떻게 발생하는지를 통제합니다. 모든 transition은 기본적으로 linear 함수를 사용하는데, 이는 transition이 끝날 때까지 속성이 균등하게 변경됨을 의미합니다.

.selector {
  transition: transform 1s linear;

  /* OR */
  transition-property: transform;
  transition-duration: 1s;
  transition-timing-function: linear;
}

여기서 중요한 것은 우리가 사는 세상은 직선적인 움직임만이 다가 아니라는 것 입니다. 직선적인 움직임은 실제로 물체가 움직이는 방식이 아닙니다. 때로는 가속하고 때로는 감속도 합니다. transition-timing-function을 사용하면 이 모든 것을 적용할 수 있습니다.

공터에서 테니스 공을 던지는 상황을 가정하면 공은 최고속도로 던지는 사람의 손을 떠나고, 공은 움직이면서 에너지를 잃고 감속하고 결국은 정지하게 됩니다. 이것을 ease-out이라고 부릅니다. 이런 움직임에는 타이밍 함수가 적용되어있습니다.

.selector {
  transition-timing-function: ease-out;
}

이제 차를 타고있다고 생각해 보겠습니다. 처음에는 움직이지 않고 정지해 있습니다. 그 다음 가속 패달을 밟으면 차가 움직이면서 최고 속도를 향해 가속됩니다. 이것을 ease-in이라고 합니다. 여기에도 타이밍 함수가 적용되어있습니다.

.selector {
  transition-timing-function: ease-in;
}

ease-in과 ease-out이 있으니 둘을 합친 타이밍 함수도 있습니다. ease-in-out 입니다. (transition이 1초 이상 지속되지 않는 한 transition에 ease-in-out을 사용하지 않는 것이 좋습니다. 어떤 물체라도 1초 안에 쉽게 가속 감속이 이루어지지 않습니다. 그냥 이상하게 보일 뿐 입니다.)

.selector {
  transition-timing-function: ease-in-out;
}

다음의 예제를 보면 타이밍 함수에 대해서 좀더 쉽게 이해할 수 있을 것 입니다.

See the Pen transition timing function by shinyks (@shinyks) on CodePen.

마지막으로 위의 선택사항이 마음에 들지 않으면 cubic-bezier를 사용하여 자신만의 타이밍 함수를 만들 수 있습니다.

cubic-bezier를 사용해 자신만의 타이밍 함수 만들기

cubic-bezier는 transition-timing-function을 결정하는 네 가지 값의 집합입니다. 사용 방법은 다음과 같습니다.

.selector {
  transition-timing-function: cubic-bezier(x1, y1, x2, y2);
}

x1, y1, x2, y2 같은 값을 어떻게 만들어낼지 걱정하지 않아도 됩니다. 숫자를 직접 입력하여 cubic-bezier 곡선을 작성하지 않아도 됩니다.(이미 숫자의 의미를 알고 있고 완벽한 타이밍 기능을 사용하지 않는 한)

Chrome과 Firefox의 개발자 도구를 사용하여 베지어 곡선을 만들 수 있습니다. 이를 사용하려면 크롬에서 F12를 눌러 개발자 도구를 켠 다음 transition이 적용된 HTML 요소를 선택한 다음 스타일 속성에 물결 아이콘을 누르면 편집을 할 수 있습니다.

애니메이션을 위한 나만의 베지어 곡선을 만드는 것에 대해 깊이 있는 자료는 이 포스트의 범위를 넘어가서 다루지 않겠습니다. 베지어 곡선에 관심이 있다면 Stephen Greig의 "CSS 타이밍 함수 이해"에서 cubic-bezier 곡선에 대한 더 많은 정보를 찾을 수 있습니다.

두 개 이상의 transition 속성

transition 또는 transition-property 속성에서 쉼표로 구분하여 두 개 이상의 CSS 속성을 다룰 수 있습니다. transition 시간, 타이밍 함수 및 딜레이에 대해서도 동일한 작업을 수행할 수 있습니다. 값이 같으면 하나만 입력하면 됩니다.

.selector {
  transition: background-color 1s ease-out, color 1s ease-out;

  /* OR */
  transition-property: background, color;
  transition-duration: 1s;
  transition-timing-function: ease-out;
}

주의할 사항은 모든 transition-property에 all로 입력하는 것 입니다. 절대 이러지 말기를 바랍니다. 이는 성능에 안좋습니다. 항상 애니메이션 효과를 줄 속성을 정확히 지정하기 바랍니다.

/* 이렇게 하지 마세요 */
.selector {
  transition-property: all
}

/* 이렇게 지정해 주세요 */
.selector {
  transition-property: background-color, color, transform;
}

transition이 먹힐 때 vs transition이 빠질 때

가끔 속성이 먹힐 때와 속성이 빠질 때의 값을 다르게 하고 싶을 때가 있습니다. transition 시간, 타이밍 함수 및 딜레이에 대해서 말입니다. 이렇게 하려면 다음의 예제와 같이 또다른 transition-property를 추가하면 됩니다.

.button {
  background-color: #33ae74;
  transition: background-color 0.5s ease-out;
}

.button:hover {
  background-color: #1ce;
  transition-duration: 2s;
}

transition 속성이 pseudo 클래스에 의해 적용될 때에는 원래 적용되었던 transition 속성에 :hover 때의 transition 속성이 덮어써집니다. 그래서 위의 코드를 실행하여 버튼에 마우스를 올리면 배경색이 2초 동안 서서히 변합니다. 이 후 마우스를 버튼 밖으로 빼면 배경색은 0.5초만에 변경되게 됩니다. 왜냐하면 마우스가 :hover 상태가 아니기 때문에 2초라는 설정은 어디에도 없기 때문입니다.

정리

CSS transition은 애니메이션을 수행하는 가장 쉬운 방법입니다. transition 축약 속성 또는 transition-property를 사용하여 애니메이션을 만들 수 있습니다.

transition을 생성하려면 클래스(또는 pseudo 클래스)의 속성을 덮어쓰고 transition이나 transition-property에 적용할 속성을 지정합니다.

애니메이션을 더 리얼하게 보이도록 하려면 transition-timing-function을 변경하는 것을 잊지 말기 바랍니다.

관련 글

자바스크립트 버튼 클릭

자바스크립트 버튼 눌림 효과

CSS 애니메이션

반응형

댓글