-
[번역] 개별 transform 속성으로 CSS transform을 더 세밀하게 조정하기CSS 2022. 10. 18. 23:24
원문 글: https://web.dev/css-individual-transform-properties/
이 글은 상기 원문 글을 한국어로 번역한 내용입니다.
Finer grained control over CSS transforms with individual transform properties
Learn how you can use the individual translate, rotate, and scale CSS properties to approach transforms in an intuitive way.
web.dev
하나의 element 에 transform을 적용하려면 CSS transform 이라는 property(속성)을 사용할 수 있다. 이 속성은 하나 이상의 <transform-function>을 차례대로 적용한다.
.target { transform: translateX(50%) rotate(30deg) scale(1.2); }
여기서 target 이라는 클래스이름을 가진 element는 x 축으로 50%, 30도 회전, 그리고 120% 확대된다.
이처럼 transform 속성을 활용하는 것도 좋지만, 만일 이 값을 각각의 element에서 변경하려고 하면 약간 지루해질 수 있다. 예를 들어 마우스 hover 이벤트가 발생할 때만 해당 element의 크기를 변경하려면 transform 속성의 변하지 않는 값들을 한 번 더 써줘야한다.
.target:hover { transform: translateX(50%) rotate(30deg) scale(2); // scale() 의 값만 바뀌었음. 나머지는 중복. }
개별 transform 속성들
개별 transform 속성(scale, rotate, translate)은 Chrome 104 버전부터 지원되고 있다. (현재는 Firefox 72, Edge 104, Safari 1.4에서도 지원하고 있다!) 이 개별 속성들을 통해 해당하는 부분만 transform 속성을 적용시켜줄 수 있다.
주의할 점: 모든 transformation 기능들이 딱 맞아 떨어지는 개별 속성들을 갖고 있는 것은 아니다.
ex. skewX() 와 matrix()앞서 보았던 target class의 transform 속성을 개별 속성들을 이용해서 쓴다면, 다음과 같이 써줄 수 있다.
.target { translate: 50% 0; rotate: 30deg; scale: 1.2; }
적용되는 순서
transform 속성과 새로운 개별 tranform 속성의 차이점 중 하나는 바로 어떤 순서로 transform이 선언되었는지에 따라 적용되는 순서가 달라진다는 점이다.
기존 transform 속성에서는 관련 속성들이 왼쪽(바깥쪽)에서 오른쪽(안쪽) 순서대로 적용된다.
반면 개별 transform 속성에서는 선언된 순서대로 적용되는 것이 아니라, translate(바깥쪽) > rotate > scale(안쪽)의 순서대로 속성들이 적용된다.
즉, 다음 두 코드 스니펫들은 같은 결과를 낸다고 볼 수 있다.
// 안에서 선언된 순서는 다르지만, 둘 다 개별 transform 속성들을 사용했기 때문에 적용된 결과는 같다. // translate가 x축 방향으로 50% 적용되고 > 30도 rotate 된 다음 > 1.2배만큼 scale 될 것이다. .transform--individual { translate: 50% 0; rotate: 30deg; scale: 1.2; } .transform--individual-alt { rotate: 30deg; translate: 50% 0; scale: 1.2; }
만일 개별 transform 속성 중 하나가 transform 속성과 함께 선언되면 개별 transform 속성(translate, rotate, scale)이 먼저 적용되고 마지막으로 transform 속성 (요소 안쪽)이 적용된다.<- spec 참조
애니메이션
이러한 개별 속성이 추가된 주된 이유는 애니메이션을 더 쉽게 만들기 위해서이다. 다음과 같이 요소에 애니메이션을 적용할 것을 가정해본다:
https://web.dev/css-individual-transform-properties/ 기존의 transform 사용하기
기존의 transform을 사용하여 이 애니메이션을 구현하려면 각 key frame에 정의된 모든 transform이 일어나는 순간에 대한 중간 값들이 계산되어 들어가야한다. 예를 들어, 10% 지점에서 회전 효과를 구현하려면 transform 에는 모든 속성들이 함께 기입되어야하기 때문에 다른 변환에 관련된 속성값들도 계산하고 기록해주어야한다.
https://web.dev/css-individual-transform-properties/ @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; }
새로운 개별 transform 속성 사용하기
반면 개별 tranform 속성을 사용한다면 훨씬 쉽게 CSS를 작성할 수 있다. 모든 변환이 일어나는 keyframe 들마다 중간값을 계산하는 대신, 각각의 변환이 일어나는 지점만을 개별적으로 정하면 된다.
@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; }
애니메이션 각 단계마다 코드를 keyframe 단위로 나누어 코드를 좀 더 모듈화시킬 수도 있다.
@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 속성들이 되어 서로를 덮어쓰는 일이 없어진다. 이렇게 하면 코드를 다시 쓰지 않고도 각각의 변환이 일어나야하는 타이밍을 다르게 부여할 수 있다!
성능
translate, rotate, 그리고 scale 애니메이션은 기존 transform을 사용하는 애니메이션과 동일한 방식으로 compositor(합성기)에서 실행된다. 따라서 개별 transform 속성을 사용하는 애니메이션은 기존 transform을 사용하는 애니메이션과 성능의 차이가 없다.
이 새로운 개별 tranform 속성은 will-change 속성과도 함께 작동한다. 일반적으로 will-change를 최소한의 필요한 요소들에만 사용하며, 가능한 짧은 시간동안 합리적으로 사용하는 것이 좋다. 하지만 가능한 한 구체적으로 정의 및 사용하는 것도 좋다. 예를 들어 will-change를 사용해서 rotate와 filter속성으로 이루어진 애니메이션을 최적화하는 경우, will-change: rotate, filter; 를 선언 및 사용하는 것이 will-change: transform을 사용하는 것보다 약간 낫다. 이는 will-change를 transform과 rotate에 사용할 때 Chrome이 미리 생성하는 일부 데이터 구조가 다르기 때문이다.
'CSS' 카테고리의 다른 글
[scss] react-data-grid 에서 기본 sorting 화살표 보여주기. (0) 2022.05.20 hex color 에서 밝기를 어떻게 추출할 수 있을까? (0) 2022.04.14