본문 바로가기

FrontEnd

CSS 애니메이션 : Transition

반응형

Tansform으로 변환을 했다면,

Transition으로 이전과 이후를 이어줍니다.

전환은 고도로 구성할 수 있지만 두 가지 값만 필요합니다.
  • 애니메이션을 적용하려는 속성의 이름
  • 애니메이션의 지속 시간
여러 속성에 애니메이션을 적용하려는 경우 쉼표로 구분된 목록을 전달할 수 있습니다.
all도 가능하지만... 애니메이션은 소금과 같습니다. 너무 많으면 요리가 망합니다.
.btn {
  transition: transform 250ms, opacity 400ms;
}
.btn:hover {
  transform: scale(1.2);
  opacity: 0;
}

Timing functions

웹에서 "모션"에 대해 이야기할 때 실제로는 시뮬레이션된 동작에 대해 이야기하고 있습니다.

픽셀 자체는 디스플레이에서 움직이지 않습니다. 즉 원리는 플립북이나 마찬가지입니다.

각 프레임마다 요소를 하나씩 그릴 뿐이지 실제로 움직이는게 아닙니다.

linear

요소는 같은 속도로 움직입니다.

시간 경과에 따른 변위

.btn {
  transition: transform 250ms;
  transition-timing-function: linear;
}
/* 이렇게도 가능 */
.btn {
  transition: transform 250ms linear;
}
linear가 최선의 선택인 경우는 거의 없습니다.
현실 세계에서 이런 식으로 움직이는 것은 거의 없습니다.
좋은 애니메이션은 자연 세계를 모방하므로 더 유기적인 것을 선택해야 합니다!

ease-out

성난 황소처럼 돌진하다 에너지가 바닥납니다.

화면 밖에서 무언가가 들어올 때 가장 일반적으로 사용됩니다(예: 모달 in)

시간 경과에 따른 변위


ease-in

이즈 인은 이즈 아웃의 반대입니다. 느리게 시작하여 속도가 빨라집니다.

화면 밖으로 무언가가 나갈 때 가장 일반적으로 사용됩니다(예: 모달 out)

시간 경과에 따른 변위


ease-in-out

위의 두 개를 합해둔 느낌입니다.

루프에서 발생하는 일에 가장 유용합니다(예: 요소 페이드 인 및 아웃, 반복).


ease (기본값)

ease-in-out과 비슷한데 대칭이 아닙니다. 짧게 가속하고 오래 감속합니다.

easy는 기본값입니다. 타이밍 기능을 지정하지 않으면 easy가 사용됩니다.
대부분의 경우 ease는 훌륭한 옵션입니다.
특별히 다른 효과를 주려는 경우가 아니라면 간편함이 매우 합리적입니다.
시간은 일정합니다.

타이밍 함수는 애니메이션이 얼마나 빨리 완료되어야 하는지가 아니라
고정된 시간 간격 동안 값이 0에서 1이 되어야 하는 방법을 설명합니다.
일부 타이밍 함수는 더 빠르거나 느리게 느껴질 수 있지만
정확하게 정의된 시간 동안만 동작합니다.

 


Custom curves

제공된 기본 제공 옵션이 필요에 맞지 않는 경우 큐빅 베지어 타이밍 함수를 사용하여 사용자 정의 easing 커브를 정의할 수 있습니다.
.btn {
  transition:
    transform 250ms cubic-bezier(0.1, 0.2, 0.3, 0.4);
}

지금까지 본 모든 값은 실제로 이 큐빅 베지어 함수에 대한 사전 설정일 뿐입니다.
linear css 값은 cubic-bezier(0, 0, 1, 1)로 나타낼 수도 있습니다.
사용자 정의 곡선을 만드는 것은 어려울 수 있지만 매우 가치가 있습니다.
내가 선택한 도구와 사용 방법을 Treasure Trove(cubic-bezier)에서 공유합니다.
혹은 extended set of timing functions에서 찾아보는 것도 나쁘지 않습니다.


Delays

중첩된 탐색 메뉴 위로 마우스를 가져갔지만 거기에 도달하기 전에 해당 메뉴가 닫힌 적이 있나요?

JS 개발자라면 왜 이런 일이 발생하는지 이해할 수 있을 것입니다.

드롭다운은 마우스가 위에 있는 동안에만 열려 있습니다.

마우스를 대각선으로 움직여 자식을 선택하면 커서가 범위를 벗어나고 메뉴가 닫힙니다.

 

이 문제는 JS 없이 CSS로 해결할 수 있습니다.

transition-delay를 사용할 수 있습니다.

.dropdown {
  opacity: 0;
  transition: opacity 400ms;
  transition-delay: 300ms;
}
.dropdown-wrapper:hover .dropdown {
  opacity: 1;
  transition: opacity 100ms;
  transition-delay: 0ms;
}

transition-delay를 사용하면 잠시 동안 현상을 유지할 수 있습니다.
.dropdown-wrapper 외부로 마우스를 이동하면 300ms 동안 아무 일도 일어나지 않습니다.
마우스가 해당 300ms 창 내에서 요소를 다시 입력하면 전환이 발생하지 않습니다.
 

shorthand 표기법

.dropdown {
  opacity: 0;
  transition: opacity 250ms 300ms;
}

Doom flicker

 

 

이 문제를 해결하기 위해 트리거와 이펙트를 분리합니다.

부모 (<button>)에 대한 호버링을 수신하고,

변환을 자식 요소에 적용합니다.

이렇게 하면 호버 대상이 커서 아래에서 밖으로 이동하지 않습니다.

<style>
  .btn {
    width: 100px;
    height: 100px;
    border: none;
    background: transparent;
    padding: 0;
  }
  
  .btn:hover .btn-contents {
    transform: translateY(-10px);
  }
  
  .btn-contents {
    display: grid;
    place-content: center;
    height: 100%;
    border-radius: 50%;
    background: slateblue;
    color: white;
    font-size: 20px;
    font-weight: 500;
    line-height: 1;
    transition: transform 250ms;
  }
</style>

<button class="btn">
  <span class="btn-contents">
    Hello World
  </span>
</button>

이것은 JavaScript의 mouseEnter 이벤트처럼 호버 상태가 버블업되기 때문에 작동합니다.

.btn-contents 위로 마우스를 가져가면 모든 상위 항목(.btn, body 등)도 마우스오버됩니다.

 

예제 : Translated cards & Photo zoom

위의 Doom flicker와 아이디어가 비슷합니다.

  • 이벤트 수신을 부모에
  • transform을 자식에 겁니다.

추가로 zoom에는 wrapper에 overflow:hidden 속성을 넣어줍니다. 💯 

 

반응형