(번역) 더 나은 CSS 트랜지션 및 애니매이션을 위한 10가지 팁

원문: Ten tips for better CSS transitions and animations

이 글은 CSS의 이징(easing) 및 큐빅 베지어(cubic-bezier) 커브 이해하기 게시물에 대한 후속 글입니다.

이 글을 보러 오셨거나 CSS cubic-bezier 커브에 대해 아직 잘 모르신다면 지금 바로 해당 글을 읽어보시기 바랍니다.

직감이 어디서 왔는지 정확히 알 수 없거나 그 직감이 정확히 무엇인지 말로 표현할 수 없더라도 경험해 보면 알 수 있는 것들이 있습니다.

인테리어에 대해 아무것도 모르지만 잘 디자인된 공간에 있으면 그곳의 느낌을 받을 수 있습니다.

마찬가지로, 어떤 앱이 다른 앱보다 더 나은 느낌을 주는 이유를 설명할 수 없더라도 좋은 앱과 나쁜 앱을 구분할 수 있습니다.

또한 사용자는 웹사이트와 앱의 트랜지션이나 애니메이션이 무엇인지 잘 모를 수도 있지만, 좋은 것과 나쁜 것의 차이를 예리하게 파악할 수 있습니다. 앱의 움직임이 좋을 때와 그렇지 않을 때를 직관적으로 알 수 있으며, 그 방법이나 이유를 설명할 수 없더라도 일반적이거나 세련되지 않다는 인상을 받을 수 있습니다.

따라서 이러한 느낌을 주는 요소에 대해 더 잘 이해하고, 자체 UI를 구축할 때 나쁜 느낌을 피하는 방법을 알아보기 위해 지난 10여 년 동안 웹에서 트랜지션과 애니메이션을 제작하면서 배운 내용을 정리했습니다.

참고 :

“트랜지션”과 “애니메이션”은 CSS에서 별개의 개념이지만 여기서는 “모든 종류의 움직임 또는 변화”라는 의미로 이 두 단어를 대부분 같은 의미로 사용하겠습니다.

1. 생각보다 짧게 작성하세요

시간과 노력을 쏟아부어 멋진 트랜지션을 만들었다면 이를 즐기고 싶을 것입니다. 저를 비롯한 대부분의 개발자는 멋진 애니메이션을 감상하며 트랜지션이 왔다 갔다 하는 모습을 보며 즐거워할 수도 있습니다. 하지만 여기 문제가 있습니다.

잘못 개발된 움직임의 절대적인 단점 1순위는 너무 오래 지속된다는 점입니다.

사용자들은 여러분만큼 흥미를 느끼지 못하며, 따라서 인내심도 없습니다. 그들은 무언가를 완료하기 위해 웹사이트에 방문했으며, 아무리 멋진 기능이라도 필요 이상으로 오래 기다리는 것을 좋아하지 않습니다.

조언을 드리자면, 사용자가 트랜지션을 놓치지 않는 범위 내에 가능한 짧게 지속하는 것이 좋습니다. 경험상 대부분의 단일 트랜지션의 경우 150~400밀리 초 범위(0.15~0.4초)에서 가장 잘 작동하는 것으로 나타났습니다. 예를 들어 한 요소가 사라졌다가 다른 요소가 나타나는 등 연속적인 트랜지션을 사용하는 경우에는 그 속도를 두 배로 늘리고 그 사이에 약간의 시간도 추가할 수 있습니다. (두 개의 개별 애니메이션이 동시에 나타나는 것은 원하지 않을 것입니다.)

너무 빠르다고 느껴질 때까지 계속 속도를 높인 다음 조금만 속도를 줄이세요.

하지만 항상 예외는 존재하며 페이지의 변화가 클수록 트랜지션을 더 눈에 띄게 만들어야 합니다. 예를 들어 카트에 있는 품목 수가 업데이트될 때 작은 애니메이션으로 강조하는 것과 전체 페이지가 트랜지션을 하는 것 사이에는 큰 차이가 있습니다. 큰 변경사항은 너무 빠르게 지나가지 않도록 하세요.

마지막으로 한 가지 주의할 점은 애니메이션의 지속 시간이 실제 지속 시간보다 짧게 느껴질 수 있다는 점입니다. 매우 느린 ease-in으로 트랜지션을 시작하면 바로 시작되지 않은 것처럼 보일 수 있고, 반대로 긴 꼬리를 가진 트랜지션은 실제로는 끝나기 전에 이미 끝난 것처럼 보일 수 있습니다. 이 점을 염두에 두세요. 사용자가 트랜지션을 지각하는 건 현실이므로 코드의 기술적인 지속 시간보다 실제로 어떻게 느껴지는지가 더 중요합니다.

2. 커브를 동작에 맞추세요

물론 이것은 말처럼 쉬운 일이 아닙니다. “좋아요, 하지만 주어진 상황에서 어떤 종류의 큐빅 베지어(cubic bézier) 커브를 사용해야 하는지 실제로 어떻게 알 수 있나요?“라고 말할 수 있습니다.

만족스럽지 못하겠지만 이에 대한 대답은 시행착오(경험이라고도 합니다)가 최고의 선생님이라는 것입니다.

움직임은 색상만큼이나 주관적이지만 그만큼 중요합니다. 웹사이트나 웹 앱의 느낌과 브랜딩의 핵심적인 부분이기 때문입니다.

하지만 한 가지 명심해야 할 요령이 있습니다. 실험할 때 실제 세계의 움직임을 떠올리고 이를 앱에서 작업 중인 움직임과 비교해 보세요. 이러한 트랜지션이 나타나고 제자리로 슬라이딩되는 것이 제대로 확인되나요? 그렇다면 열심히 일을 마친 보고자가 달려와 일을 끝냈다는 것을 알리는 것과 같이 빠른 속도의 인트로와 부드럽고 빠른 ease-out을 함께 사용하는 빠른 속도의 트랜지션을 사용해야 할 수도 있습니다.

화면에 실패 메시지가 표시되는 것은 어떨까요? 이 경우 약간의 주의를 끌기 위해 약간 느린 이징 커브가 필요할 수 있습니다.

즉시 알려야 하는 중요한 사항이라면 속도와 명확성을 최우선으로 고려할 수 있습니다. 매우 중요한 내용이라면 흔들기와 같은 보다 적극적인 움직임을 통해 심각성을 전달하고 필요한 곳에 주의를 집중시킬 수도 있습니다.

따라서 제가 가장 추천하는 것은 시간을 투자하여 해당 동작이 적절한 느낌을 전달하는지 물어보는 것입니다. 이 움직임이 제품 또는 페이지의 브랜드와 일관성이 있나요?

만약 Pixar에서 여러분의 UI와 같은 동작을 수행하는 로봇을 애니메이션으로 제작한다면 어떻게 움직일까요?

3. 가속과 감속을 사용하세요

실제 세계에서는 어떤 유형의 움직임도 즉시 최대 속도로 점프하거나 순식간에 완전히 완전히 멈추는 경우는 거의 없습니다. 따라서 이러한 움직임을 만드는 커브를 피하면 UI가 좀 더 ‘진짜’ 같고 직관적으로 보일 것입니다.

애니메이션이 뭔가 이상해 보인다면, 시작이나 끝이 부자연스럽게 갑작스럽기 때문일 가능성이 높습니다.

조금이라도, cubic-bezier 커브에 약간의 ease in과 out을 추가하는 것이 좋습니다. 작지만 감지할 수 있는 약간의 가속 및/또는 감속이 부드러운 느낌의 트랜지션과 약간 어색한 느낌의 트랜지션의 차이를 만들 수 있습니다.

아래는 네 개의 사각형이 모두 한 바퀴 회전하지만 서로 다른 이징(easing)이 적용된 데모입니다.

위의 첫 번째와 두 번째 사각형은 너무 갑작스럽게 시작하거나 끝나는 것처럼 보입니다.

세 번째 “부드러운(smooth)” 옵션은 커스텀 커브가 부드럽게 들어오고 나가면서 가속 및 감속이 더욱 우아하게 움직이기 때문에 훨씬 더 잘 작동합니다.

실제 물리학이 적용된 듯한 애니메이션을 더 구현하고 싶다면 네 번째 ‘관성(inertia)’ 옵션을 사용하면 마치 스프링에 의해 구동되는 것처럼 ‘와인드업(winds up)’ 및 오버슈팅이 가능합니다. (이런 유형의 애니메이션에서는 조금만 추가해도 큰 효과를 얻을 수 있으니 참고하세요.)

하지만 갑작스러운 시작과 멈춤에 대해 한 가지 중요한 점은 사용자가 볼 수 없는 경우에는 괜찮다는 것입니다. 해당 오브젝트가 페이드 인하는 경우 애니메이션의 시작을 애초에 인지할 수 없으므로 갑자기 시작해도 무방합니다.

그 반대도 마찬가지입니다. 요소가 opacity: 0으로 희미해지는 경우, 어차피 마지막에는 표시되지 않기 때문에 트랜지션 커브가 정확히 어떻게 끝나는지는 중요하지 않습니다.

4. 적은 것이 더 많은 것입니다

이 팁의 대부분을 “적은 것이 더 많습니다”로 요약할 수 있습니다.

페이지의 모든 요소를 전부 애니메이션으로 만들어 넣고 싶은 유혹에 빠지기 쉽습니다. (저도 분명히 그런 적이 있습니다.) 하지만 개인 웹사이트라서 약간 과격하게 만들고 싶은 경우를 제외하고는, 너무 많은 움직임은 득 보다 실이 많을 수 있습니다. CSS로 트랜지션 할 때는 일반적으로 과장하기보다는 절제하는 편이 좋습니다.

애니메이션 중에 요소가 많이 바뀔수록 트랜지션이 과도하게 보일 위험이 있습니다.

opacity를 0에서 1로(또는 그 반대로) 애니메이션 하는 경우, 0.4에서 1과 같이 더 작은 범위로 시도해 보세요. 요소가 전체 크기로 확장되는 경우, 보이지 않을 정도로 작게 만들지 말고, 시작할 때 너무 극적이지 않은 작은 변화를 시도해 보세요.

어떤 요소가 다른 자리로 이동하나요? 대부분의 경우, 이러한 움직임은 약 5~40픽셀 범위에서 이루어져야 합니다. 이보다 짧으면 움직임이 너무 미묘해서 눈치채지 못할 수 있고, 너무 길면 부드러운 슬라이드가 어색하게 느껴질 수 있습니다.

다음은 opacity, translateYscale을 애니메이션 하는 트랜지션의 예시입니다. 먼저 등장하지만 비교적 긴 애니메이션(주황색)과 조금 더 간소화하고 빠르게 표현한 애니메이션(파란색)을 비교해 보세요.

너무 많은 것을 하는 것은 아무것도 하지 않는 것보다 나쁠 수 있습니다. 따라서 트랜지션이 충분히 효과적일 수 있는 지점을 찾고, 그 이상 나아가야 한다면 신중하게 진행하세요.

5. 브라우저 기본값으로 설정하지 마세요

브라우저에 linear, ease, ease-in, ease-out, 그리고 ease-in-out과 같은 몇 가지 기본으로 제공되는 이징 커브가 있다는 것을 이미 알고 계실 것입니다.

하지만 이 다섯 가지 타이밍 기능은 일부 상황에서 편리하고 유용하지만 매우 보편적이기도 합니다. (온라인 도구와 라이브러리에 내장된 애니메이션 중 상당수도 선택의 폭이 넓긴 하지만 동일한 표현방식에 빠지게 되기 쉽습니다).

움직임을 최대한 활용하고 싶다면, 가장 일반적인 기본적으로 명명된 옵션을 벗어나보는 것이 좋습니다.

Bootstrap이나 Tailwind를 기본값으로 사용하여 구축한 사이트가 일반적으로 보일 위험이 있는 것처럼, 일반적인 이징 커브는 UI를 단조롭고 획일적으로 보이게 만들 수 있습니다.

이에 대한 대안으로 VS Code에는 다양한 옵션이 있는 cubic-bezier 커브에 대한 놀라운 자동 완성 기능이 있습니다. CSS 컨텍스트에서 cubic-bezier를 입력하기 시작하면 다음과 같은 드롭다운이 표시됩니다.

이 모든 프리셋을 살펴보고 사용해 보고 싶으시다면 제 이징 플레이그라운드에서 다루고 있습니다.

또 다른 훌륭한 옵션은 브라우저의 개발 도구를 열고 그 안에 있는 이징 커브를 사용해 보는 것입니다.

모든 주요 브라우저에는 다양한 옵션을 시도하고 조정할 수 있는 샌드박스로 사용할 수 있는 이징 패널이 있습니다. 이 패널에 액세스 하려면 개발 도구를 열고 CSS 스타일 패널에서 cubic-bezier 값 옆에 있는 커브 아이콘을 클릭합니다. (아이콘은 다르지만 워크플로우는 기본적으로 모든 브라우저에서 동일합니다.)

하지만 이징 커브를 어떻게 정의하든, 시간을 들여 미세하게 조정하는 것이 좋습니다. cubic-bezier를 사용하고 수정하는 것을 두려워하지 마세요.

브라우저 또는 VS Code의 프리셋을 활용하면 충분히 사용할 수 있습니다. 만약 키워드 값 대신에 cubic-bezier를 사용하고 있다면, 이미 게임에서 앞서가고 있는 것입니다.

여러분이 컬러 팔레트로 미리 정의된 CSS 네임드 컬러만 사용하도록 제한하길 원치 않을 것입니다. 따라서, 당신의 트랜지션 또한 소수의 미리 정의된 커브에만 제한되지 않기를 바랍니다.

6. 여러 프로퍼티에 여러 이징을 활용하세요.

이 기능이 항상 유용한 것은 아니지만, transform으로 항목의 크기를 조정할 때 opacity도 변경되는 경우처럼, 단일 요소에 한 번에 두 개 이상의 프로퍼티를 애니메이션 하는 경우가 있을 수 있습니다.

다음과 같이 두 프로퍼티에 동일한 cubic-bezier 커브를 적용할 수 있습니다.

/* ⛔ 좋지만 더 나아질 수 있습니다. */
.my-element {
  transition: all cubic-bezier(0.5, 0, 0.5, 1) 0.5s;
}

/* ⛔ 이 또한 이상적이지는 않습니다. */
@keyframes scale_and_appear {
  from {
    opacity: 0;
    transform: scale(0);
  }
}

.my-element {
  animation: scale_and_appear 0.5s cubic-bezier(0.5, 0, 0.5, 1) forwards;
}

경우에 따라서는 괜찮아 보일 수도 있습니다. 그러나 트랜지션 되는 모든 프로퍼티에 대해 동일한 커브가 실제로 동작하지 않는 상황이 있을 수 있습니다.

transform에 잘 작동하는 이징 커브가 페이드에는 적합하지 않을 수 있습니다. 이럴 때는 CSS 프로퍼티별로 고유한 이징을 설정하는 것이 편리합니다.

이러한 경우 @keyframes 애니메이션을 프로퍼티별로 분할하거나 여러 transition을 지정할 수 있습니다. 그런 다음 transitionanimation 모두 여러 값을 허용할 수 있으므로 각 프로퍼티마다 다른 커브를 지정할 수 있습니다.

/* 👍 각 프로퍼티에 고유한 커브가 있기 때문에 더 좋습니다. */
.my-element {
  transition: opacity linear 0.5s, transform cubic-bezier(0.5, 0, 0.5, 1) 0.5s;
}

/* 👍 두 개의 애니메이션을 사용하여 둘 다 적용합니다. */
@keyframes scale {
  from {
    transform: scale(0);
  }
}

@keyframes appear {
  from {
    opacity: 0;
  }
}

.my-element {
  animation: scale 0.5s cubic-bezier(0.5, 0, 0.5, 1) forwards, appear 0.5s
      linear forwards;
}

다음은 데모입니다. 상자가 번갈아 가며 들어오고 나갈 때 왼쪽 사각형의 opacityscale이 동일한 가속도를 따르는 것을 볼 수 있습니다. 그러나 오른쪽에서는 opacity가 고유한 선형 커브를 따릅니다.

어느 것이 더 낫나요? 글쎄요, 그것은 여러분이 원하는 효과가 무엇인지에 따라 다릅니다.

다시 말하지만, 이 기능은 자주 사용되지는 않지만 매우 편리하고 잊어버리기 쉽기 때문에, 이번 목록에서 한 자리를 차지했습니다.

각 프로퍼티의 지속시간을 변경할 수도 있지만, 너무 엉뚱하게 설정하면 동기화가 제대로 되지 않을 수 있으니 조심해야 합니다.

7. 단계적 지연(staggered delay)을 사용하세요

여러 요소(또는 여러 부분으로 구성된 하나의 요소)를 트랜지션 할 때 animation-delay 또는 transition-delay이 가져올 수 있는 효과를 과소평가해서는 안 되며, 특히 단계적인 지연을 사용할 때 더욱 그렇습니다.

각 줄마다 새로운 종류의 애니메이션 지연을 사용하여 서로 다른 효과를 만들어내는 이 CodePen 예시를 살펴보세요.

위의 예시에서 첫 번째 줄은 한꺼번에 트랜지션 됩니다. 괜찮지만 특별히 눈에 띄게 선명하지는 않습니다.

그다음에 이어지는 각 줄에는 각 글자에 다양한 정도의 지연이 적용되어 재미있는 “바운스 인” 효과를 연출합니다. 심지어는 거꾸로 표시되는 줄도 있고, 중간에서 바깥쪽으로 표시되는 줄도 있습니다.

그러나 적은 것이 더 많다는 것을 기억하세요. 특히 트랜지션 되는 요소가 많을 때는 이런 애니메이션을 과도하게 사용하기 쉽습니다. 이 예제는 데모 목적으로 일반적으로 권장하는 것보다 훨씬 더 과장되게 만들었으며, 일반적인 UI 작업에서는 너무 번잡해 보일 수 있습니다.

하지만 이 효과를 좀 더 섬세하게 적용할 수 있는 기회도 있습니다. 예를 들어 로딩 화면에 점을 넣는 것은 어떨까요? 드로어나 햄버거 메뉴가 열릴 때 각 항목이 약간 지연된 상태로 표시되는 것은 어떨까요?

다시 말하지만, 짧고 간결하게 유지하세요. 하지만 단계적 지연을 잘 적용하면 웹 트랜지션을 한 단계 더 발전시킬 수 있습니다.

8. 안으로 들어오는 요소에는 out을, 밖으로 나가는 요소는 in을 활용하세요.

다양한 종류의 이징 커브를 살펴본 적이 있다면 ease in(천천히 시작), ease out(천천히 끝), in-out(본질적으로 둘 다, 중간은 빠르고 시작과 끝은 느림)의 세 가지 유형이 있다는 것을 알 수 있을 것입니다.

트랜지션의 까다로운 점은 다음과 같습니다. 보통 들어오는 요소에 대한 트랜지션은 ease-out으로 처리하고, 나가는 요소에 대한 트랜지션은 ease-in으로 처리하고 싶어 합니다.

제가 글을 쓰는 것만큼이나 여러분도 읽기 혼란스러웠을 것입니다. 다시 돌아가 보겠습니다.

페이지 전환이나 라이트박스에서 두 이미지 사이를 슬라이딩하는 것처럼 한 요소가 페이지를 떠나면 다른 요소가 그 자리를 대신하는 애니메이션이 있다고 가정해 보겠습니다.

사용자는 이를 하나의 UI 트랜지션으로 인식합니다. 하지만 실제로는 이전 요소가 나간 후 새 요소가 들어오는 두 가지 트랜지션입니다.

즉, 요소를 트랜지션 할 때 천천히 시작하려면 ease-in이 필요합니다.

반대로 요소가 들어오도록 트랜지션 할 때는 일반적으로 서서히 멈춰야 합니다. 그러기 위해서는 ease-out이 필요합니다.

이 두 가지를 함께 사용하면 하나의 매끄러운 움직임 효과를 낼 수 있습니다.

9. 하드웨어 가속을 활용하세요.

모든 CSS 프로퍼티가 모든 디바이스와 브라우저에서 부드럽게 애니메이션 되거나 트랜지션 될 수 있는 것은 아닙니다. 실제로 디바이스의 하드웨어 가속을 활용하여 가장 부드럽고 높은 프레임률로 트랜지션 할 수 있는 경우는 극소수에 불과합니다.

참고 :

하드웨어 가속을 활용하기 위해 하드웨어 가속이 무엇인지 이해하는 것은 중요하지 않습니다. 하지만 궁금한 점이 있다면 브라우저가 기기의 그래픽 처리 장치(GPU)의 도움을 받아 렌더링을 훨씬 빠르고 부드럽게 만들 수 있다는 것을 의미합니다(단, 특정 조건에서만 가능합니다).

항상 하드웨어 가속이 가능한 프로퍼티는 아래와 같습니다.

  • transform (translate, scale, rotate 및 모든 3D 관련 기능을 포함합니다.)
  • opacity

때때로 하드웨어 가속이 가능한 프로퍼티는 아래와 같습니다.

  • 특정 SVG 프로퍼티
  • filter, 브라우저 및 어떤 필터인지에 따라 달라질 수 있습니다.

캔버스나 WebGL과 같이 CSS가 아닌 다른 것들도 하드웨어 가속을 활용할 수 있습니다. 하지만 여기서는 자세히 설명하지 않겠습니다.

위의 모든 내용을 요약하면 다음과 같습니다.

요소를 이동, 크기 조정 또는 회전하려면 항상 CSS transform 프로퍼티를 사용하세요.

transform을 적용하면 레이아웃에 영향을 미치지 않으므로 재계산을 최소화하고 브라우저를 원활하게 작동시킬 수 있습니다. 웹에서 가장 많이 사용하는 애니메이션과 트랜지션은 대부분 transformopacity를 조합하여 구현할 수 있습니다.

하지만 어떤 작업을 하든 요소의 크기나 배치를 직접 변경하지 마세요. height, width, border, margin, padding 등 페이지에서 요소의 레이아웃에 영향을 줄 수 있는 프로퍼티를 변경하면 변경에 필요한 계산으로 인해 페이지 속도가 눈에 띄게 느려질 수 있습니다.

이러한 프로퍼티에 애니메이션을 적용해야 하는 경우 가능한 모든 장치와 브라우저에서 테스트해야 합니다. 제 경험상 Safari는 특히 iOS에서 기본적으로 애니메이션을 제대로 처리하는 데 매우 취약합니다. Firefox도 그다지 뒤처지지는 않지만 고성능 디바이스에서만 테스트하는 경우 이를 깨닫지 못할 수도 있습니다. 전 세계의 많은 사람들이 저사양 Android를 사용하고 있으므로 테스트에서 제외해서는 안 됩니다.

참고 :

하드웨어 가속이 가능하다고 해서 반드시 가속이 되는 것은 아닙니다. 최종 결정은 브라우저가 내립니다.

GPU는 더 빠르지만 더 많은 에너지를 소비한다는 잠재적인 이유도 있습니다. 따라서 기기의 전원이 부족하거나 배터리 절약 모드에 있는 경우 브라우저는 그래픽 성능보다 배터리를 선택할 수 있습니다.

10. 필요에 따라 will-change를 사용하세요.

이론상으로는 부드럽고 원활하게 작동해야 하지만 실제로는 끊기거나 삐걱거리는 애니메이션 문제가 발생하면(다시 한 번 말하지만, 저는 Safari에서 주로 이런 문제가 발생하지만 사용자마다 다를 수 있습니다) will-change 프로퍼티를 활용하세요.

기술적인 세부 사항은 자세히 설명하지 않겠지만, 기본적으로 will-change는 브라우저에 변경 사항을 알려주어(기억하기 쉽도록) 다른 계산을 건너뛸 수 있게 해 줍니다. 이는 마치 레스토랑에 일행 전체가 한정된 메뉴만 주문할 것이라고 미리 알려주는 것과 비슷하며, 주방/브라우저가 집중해야 할 사항과 신경 쓸 필요가 없는 사항을 알려줌으로써 시간을 절약할 수 있습니다.

예를 들어, 어떤 요소의 transform 프로퍼티만 변경될 것이라는 것을 확실히 알고 있고, 브라우저에 will-change: transform을 통해 이를 미리 알려줄 수 있다면 페이지에서 무언가가 변경될 때 해당 요소를 다시 렌더링 하기 위해 거쳐야 하는 다른 모든 단계를 안전하게 건너뛸 수 있습니다.

최상의 시나리오는 레이아웃에 영향을 주지 않는 프로퍼티와 함께 사용하여 브라우저가 계산을 전적으로 GPU로 넘겨 가장 높은 프레임 속도와 부드러운 성능을 얻는 것입니다.

하지만 will-change는 만병통치약이 아닙니다. 오히려 과도하게 사용하면 성능에 악영향을 미칠 수 있습니다.

브라우저는 will-change가 적용된 모든 요소에 대해 새로운 레이어(일종의 새로운 z-index 레벨)를 생성하기 때문에 결합이 조금 더 복잡해집니다. 신중하게 사용하면 이 거래는 그만한 가치가 있습니다. 하지만 부주의하게 사용하면 브라우저에 더 많은 작업을 유발할 수 있습니다. 다음은 MDN에서 인용한 내용입니다.

경고: will-change는 기존의 성능 문제를 해결하기 위한 최후의 수단으로 사용하도록 고안되었습니다. 성능 문제를 미리 예측하기 위해 사용해서는 안 됩니다.

일부 자료에서는 애니메이션이나 트랜지션 전에 will-change 기능을 적용한 다음, 나중에 제거할 것을 권장하기도 합니다.

다시 한번 강조하지만, 가장 좋은 조언은 철저하게 테스트하라는 것입니다.

보너스: 사용자의 선호도를 존중하세요

사용자는 기기 설정을 통해 축소된 모션을 선호하는지 여부를 나타낼 수 있습니다.

사용자가 이렇게 선택하는 이유는 다양합니다. 예를 들어 의료적인 이유로는 현기증, 메스꺼움 또는 과도한 움직임에 노출될 때 발작을 일으킬 수도 있습니다. 또는 사용자가 단지 움직임이 지나치게 눈에 띄어서 거슬리게 느낄 수도 있습니다.

그러나 왜 이러한 선택을 하는지는 별로 중요하지 않습니다. 우리 개발자의 일은 어떤 경우든 사용자의 선호를 수용하는 것입니다.

이를 CSS를 사용하여 미디어 쿼리를 이용해 구현할 수 있습니다. (예: 아래의 코드는 MDN에서 제공합니다.)

@media (prefers-reduced-motion) {
  /* 사용자 설정이 축소된 모션으로 설정된 경우 적용할 스타일 */
}

또는 자바스크립트를 사용할 수도 있습니다. 이 예제에서는 축소된 모션 기본 설정이 존재하는지 확인하고, 존재하는 경우 <html> 태그에 클래스를 추가합니다.

const prefersReducedMotion = window.matchMedia(
  '(prefers-reduced-motion: reduce)'
).matches;

if (prefersReducedMotion) {
  document.documentElement.classList.add('reduce-motion');
}

이 자바스크립트 예제에 따라 페이지의 대상 요소에 CSS를 추가하여 오버라이드를 설정할 수 있습니다.

.reduce-motion {
  /*  여기에 축소된 모션을 설정합니다. */
}

단, 자바스크립트를 사용할 때는 스크립트가 실행되기 전에 동작이 깜박이지 않고 자바스크립트를 비활성화한 사용자를 배제하지 않도록 페이지가 점진적으로 향상되기를 원합니다. 따라서 두 가지 기술을 혼합하는 것이 이상적입니다.

이러한 경우 CSS를 정확히 어떻게 해야 하는지에 관해서는 모션을 줄인다고 해서 모션이 없거나 애니메이션이 전혀 없는 것은 아니라는 점을 기억하세요.

제가 자주 사용하는 기법 중 하나는 키프레임 애니메이션을 변경하여 축소된 모션 기본 설정이 감지된 경우에만 투명도를 사용하도록 하는 것입니다.

@keyframes slide_in {
  from {
    opacity: 0;
    transform: translateY(2rem);
  }
}

@keyframes slide_in_reduced {
  from {
    opacity: 0;
  }
}

.animated-thing {
  animation-name: slide_in;
}

@media (prefers-reduced-motion) {
  .animated-thing {
    animation-name: slide_in_reduced;
  }
}

사용자가 최소한의 움직임을 선호한다고 해서 트랜지션을 중요하게 생각하지 않는 것은 아닙니다.

또한 모션을 그대로 유지하는 것이 더 나은 상황도 있습니다. 예를 들어 백그라운드에서 무언가가 로드될 때 진행률 표시줄을 표시하거나 오디오 또는 비디오 파일에 재생 표시기를 표시하는 경우, 이는 UI의 핵심 정보입니다. 이러한 표시기를 완전히 없애기보다는 섬세하고 눈에 거슬리지 않게 표시할 수 있는 방법을 찾아보세요. 사용자가 움직임을 숨길 수 있도록 할 수도 있습니다. 또는 정보를 다른 방식으로 표현하는 것도 좋은 방법일 수 있습니다(예를 들어 애니메이션 막대 대신 숫자 퍼센트 카운터를 사용하는 것입니다).

최소한 사용자는 동영상과 GIF를 포함한 모든 연속 애니메이션을 일시 중지할 수 있어야 합니다. 그러나 이상적으로는 사용자가 이미 보고 싶지 않다고 표시한 것을 강제로 처리하는 대신 디바이스 선호도에 따라 사용자의 요구를 예측해야 합니다.

축소 모션과 관련된 디자인에 대해 더 자세히 알아보려면 스매싱 매거진의 Val Head가 쓴 이 글을 참조하세요. 그 자체로 큰 주제이지만, 이 팁이 일반적인 지침이 되길 바랍니다.

모든 것을 종합해 보세요

이 CodePen 데모는 이 글의 팁을 모두 적용하면 UI 트랜지션의 느낌이 완전히 달라질 수 있다는 것을 보여줍니다. 양쪽의 ‘run animation’ 버튼을 클릭하면 해당 열의 항목이 트랜지션 되는 것을 확인할 수 있습니다.

둘 모두 상자의 크기 조정, 이동, 페이드인 등 기본적으로 동일한 애니메이션이 적용된다는 점을 주목하세요. 하지만 그 트랜지션(transition)의 디테일이 효과를 완전히 바꿔(transform) 놓았습니다(말장난 의도는 없습니다).

왼쪽(빨간색-주황색) 열의 항목은 단계적 지연이 없으며 투명도, 위치 및 크기가 변화하면서 한 번에 모두 페이드 인합니다. 또한 트랜지션이 꽤 오래 지속되며 브라우저의 기본 ease-out 커브를 사용하는데, 이 경우 나쁘지는 않지만 최적이라고 할 수는 없습니다.

반면 오른쪽(파란색) 열에서는 애니메이션이 단계적으로 지연되어 항목이 차례로 들어옵니다. 지연 시간과 총 트랜지션 시간은 모두 상당히 적으며 효과는 모두 그대로 유지되지만 훨씬 더 섬세합니다. 마지막으로, 커스텀 cubic-bezier 커브가 적용되었습니다.

이 데모를 통해 약간의 조정이 얼마나 큰 차이를 만들 수 있는지 쉽게 알 수 있기를 바랍니다.

마무리

웹에서 나만의 애니메이션을 제작해 보세요! 이번 포스팅이 여러분에게 흥미롭고 유용한 정보가 되었기를 바라며, 더욱 강력한 인터랙티브 경험을 제작하는 데 도움이 되기를 바랍니다.


🚀 한국어로 된 프런트엔드 아티클을 빠르게 받아보고 싶다면 Korean FE Article(https://kofearticle.substack.com/)을 구독해주세요!



Written by@[Ykss]
고이게 두지 않고 흘려보내는 개발자가 되자.

GitHubInstagramLinkedIn