개별 변환 속성으로 CSS 변환을 세밀하게 제어

translate, rotate, scale 속성으로 요소 변환

CSS transform 속성

요소에 변환을 적용하려면 CSS transform 속성을 사용하세요. 이 속성은 하나 이상의 <transform-function>를 허용하며, 이러한 <transform-function>는 차례로 적용됩니다.

.target {
  transform: translateX(50%) rotate(30deg) scale(1.2);
}

타겟팅된 요소가 X축에서 50% 변환되고 30도 회전한 후 마지막으로 120%까지 크기가 조정됩니다.

transform 속성은 제대로 작동하지만 이러한 값을 개별적으로 변경하려면 약간 번거로워집니다.

마우스 오버 시 크기를 변경하려면 값이 변경되지 않더라도 transform 속성의 모든 함수를 복제해야 합니다.

.target:hover {
  transform: translateX(50%) rotate(30deg) scale(2); /* Only the value of scale() changed */
}

개별 변환 속성

Chrome 104부터 CSS 변환의 개별 속성이 제공됩니다. 속성은 scale, rotate, translate이며, 이를 사용하여 변환의 각 부분을 개별적으로 정의할 수 있습니다.

이렇게 하면 Chrome이 이미 이러한 속성을 지원하는 Firefox 및 Safari에 합류하게 됩니다.

브라우저 지원

  • Chrome: 104.
  • Edge: 104.
  • Firefox: 72.
  • Safari: 14.1

소스

개별 속성으로 위의 transform 예시를 다시 작성하면 스니펫이 다음과 같이 됩니다.

.target {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
}

순서가 중요

원래 CSS transform 속성과 새 속성 간의 한 가지 주요 차이점은 선언된 변환이 적용되는 순서입니다.

transform를 사용하면 변환 함수가 작성된 순서대로 왼쪽 (외부)에서 오른쪽 (내부)으로 적용됩니다.

개별 변환 속성의 순서는 선언된 순서가 아닙니다. 순서는 항상 동일합니다. 먼저 translate (외부)가 표시되고 그 다음 rotate, scale (내부)가 표시됩니다.

즉, 다음 두 코드 스니펫은 동일한 결과를 제공합니다.

.transform--individual {
  translate: 50% 0;
  rotate: 30deg;
  scale: 1.2;
}

.transform--individual-alt {
  rotate: 30deg;
  translate: 50% 0;
  scale: 1.2;
}

두 경우 모두 타겟팅된 요소는 먼저 X축에서 50%로 이동한 다음 30deg로 회전하고 마지막으로 1.2로 크기 조정됩니다.

개별 변환 속성 중 하나가 transform 속성과 함께 선언된 경우 개별 변환이 먼저 적용되고 (translate, rotate, scale) 마지막으로 transform가 적용됩니다 (내부). 자세한 내용은 변환 행렬을 계산하는 방법을 정의하는 사양을 참고하세요.

애니메이션

이러한 속성이 추가된 주된 이유는 애니메이션을 더 쉽게 만들기 위해서입니다. 다음과 같이 요소에 애니메이션을 적용하려고 한다고 가정해 보겠습니다.

키프레임 그래프

transform 사용

transform를 사용하여 이 애니메이션을 구현하려면 정의된 모든 변환의 모든 중간 값을 계산하고 각 키프레임에 포함해야 합니다. 예를 들어 10% 지점에서 회전하려면 transform 속성에 모든 변환이 필요하므로 다른 변환의 값도 계산해야 합니다.

계산된 중간 값이 포함된 키프레임 그래프

결과 CSS 코드는 다음과 같습니다.

@keyframes anim {
  0% { transform: translateX(0%); }
  5% { transform: translateX(5%) rotate(90deg) scale(1.2); }
  10% { transform: translateX(10%) rotate(180deg) scale(1.2); }
  90% { transform: translateX(90%) rotate(180deg) scale(1.2); }
  95% { transform: translateX(95%) rotate(270deg) scale(1.2); }
  100% { transform: translateX(100%) rotate(360deg); }
}

.target {
  animation: anim 2s;
  animation-fill-mode: forwards;
}

개별 변환 속성 사용

개별 변환 속성을 사용하면 훨씬 더 쉽게 작성할 수 있습니다. 모든 변환을 키프레임에서 키프레임으로 드래그하는 대신 각 변환을 개별적으로 타겟팅할 수 있습니다. 또한 더 이상 중간 값을 모두 계산할 필요가 없습니다.

@keyframes anim {
  0% { translate: 0% 0; }
  100% { translate: 100% 0; }

  0%, 100% { scale: 1; }
  5%, 95% { scale: 1.2; }

  0% { rotate: 0deg; }
  10%, 90% { rotate: 180deg; }
  100% { rotate: 360deg; }
}

.target {
  animation: anim 2s;
  animation-fill-mode: forwards;
}

개별 변환 속성과 여러 키프레임 사용

코드를 모듈식으로 만들려면 각 하위 애니메이션을 자체 키프레임 집합으로 분할하면 됩니다.

@keyframes move {
  0% { translate: 0% 0; }
  100% { translate: 100% 0; }
}

@keyframes scale {
  0%, 100% { scale: 1; }
  5%, 95% { scale: 1.2; }
}

@keyframes rotate {
  0% { rotate: 0deg; }
  10%, 90% { rotate: 180deg; }
  100% { rotate: 360deg; }
}

.target {
  animation: move 2s, scale 2s, rotate 2s;
  animation-fill-mode: forwards;
}

이제 개별 속성이 된 transform 속성이 더 이상 서로 덮어쓰지 않으므로 이 분할 덕분에 원하는 대로 각 키프레임 세트를 적용할 수 있습니다. 또한 전체를 다시 작성하지 않고도 각 변환에 다른 타이밍을 지정할 수 있습니다.

성능

이러한 새 속성을 사용하는 애니메이션은 기존 transform 속성의 애니메이션만큼 효율적입니다.

translate, rotate, scale의 애니메이션은 transform의 애니메이션과 동일한 방식으로 컴포저이터에서 실행되므로 transform와 동일한 방식으로 애니메이션 성능에 적합합니다.

이러한 새 속성은 will-change 속성과도 호환됩니다. 일반적으로 will-change를 필요한 최소 개수의 요소에 최대한 짧은 시간 동안만 사용하여 과도하게 사용하지 않는 것이 좋습니다. 하지만 최대한 구체적으로 설명하는 것이 좋습니다. 예를 들어 will-change를 사용하여 rotatefilter 속성으로 애니메이션을 최적화하는 경우 will-change: rotate, filter를 사용하여 이를 선언해야 합니다. 이는 rotatefilter에 애니메이션을 적용하는 경우 will-change: transform, filter를 사용하는 것보다 약간 나은 방법입니다. will-change를 사용할 때 Chrome에서 미리 만드는 일부 데이터 구조가 transformrotate에서 다르기 때문입니다.

새로운 상호 운용성 시리즈의 일부