transform 속성은 주변 레이아웃을 바꾸지 않고 요소를 옮기고, 크기를 바꾸고, 회전하고, 기울여요. 모든 transform 함수, 함수 순서가 중요한 이유, transform-origin, 별도의 translate, scale, rotate 속성, translate(-50%, -50%) 가운데 정렬 기법을 알아봐요.
▶이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.
translate(20px, 10px)는 파란 상자를 옆으로 20px, 아래로 10px 옮겨요. scale(1.3)은 초록 상자를 가운데를 중심으로 30% 키워요. rotate(20deg)는 주황 상자를 시계 방향으로 돌리고, skewX(-20deg)는 어두운 상자를 기울여요. 모든 경우에 요소가 레이아웃에서 차지하는 공간인 점선 자리는 정확히 그대로예요.
transform 함수
함수
하는 일
예시
translate(x, y)
옮겨요
translate(20px, -10px), translate(-50%, -50%)
translateX(x) / translateY(y)
한 축으로 옮겨요
translateY(-4px)
scale(s) / scale(x, y)
크기를 바꿔요(1 = 원래, 0.5 = 절반, 음수는 뒤집기)
scale(1.1), scale(-1, 1)
scaleX(s) / scaleY(s)
한 축으로 크기를 바꿔요
scaleX(0.5)
rotate(angle)
시계 방향으로 돌려요(음수 = 반시계 방향)
rotate(45deg), rotate(0.25turn)
skew(x, y) / skewX(a) / skewY(a)
기울여요
skewX(-15deg)
matrix(a, b, c, d, e, f)
위의 모든 것을 행렬 하나로. 주로 브라우저가 돌려주는 형태
none
transform 없음
translate()의 퍼센트는 부모가 아니라 요소 자신의 크기를 기준으로 해요. 회전은 각도, turn, 회전 애니메이션을 다루는 페이지가 따로 있어요. CSS 회전을 보세요.
Transform 플레이그라운드
슬라이더를 움직여 보세요. 첫 번째 줄은 만든 transform 값이고, 두 번째 줄은 브라우저가 거기서 계산한 행렬이에요. getComputedStyle은 어떤 transform이든 이 행렬로 돌려줘요.
파란 상자는 똑바로 120px 옮겨진 다음 제자리에서 돌았어요. 초록 상자는 먼저 돌아서 "x축"이 대각선을 향하고, translateX(120px)가 대각선을 따라 아래로 옮겨요. 함수는 같은데 위치가 달라요.
다른 함정도 있어요. 두 번째 transform 선언은 첫 번째를 대체해요. 카드에 transform: rotate(-2deg)가 있고 hover 규칙이 transform: scale(1.05)라면 hover할 때 회전이 사라져요. 둘 다 반복하거나(rotate(-2deg) scale(1.05)) 아래의 개별 속성을 쓰세요.
transform-origin
크기 조절, 회전, 기울이기는 고정점, 즉 transform origin을 중심으로 일어나고, 기본값은 가운데예요. 키워드, 길이, 퍼센트로 바꿀 수 있어요.
세 상자 모두 25도 돌아요. 첫 번째는 가운데를 축으로, 두 번째는 왼쪽 위 모서리를 자리의 모서리에 고정한 채로, 세 번째는 오른쪽 아래 모서리를 고정한 채로 돌아요. 버튼에서 펼쳐지는 드롭다운 메뉴는 scale()과 함께 transform-origin: top을 써요.
translate, scale, rotate 속성
최신 브라우저에는 함수와 같은 일을 하지만 따로 지정하고 애니메이션할 수 있는 별도 속성 세 개도 있어요.
.card {
rotate: -2deg;
transition: scale 0.2s ease-out;
}
.card:hover {
scale: 1.05; /* the rotation stays, because it is a different property */
}
선언한 순서와 상관없이, 항상 어떤 transform 값 앞에 transform: translate(...) rotate(...) scale(...)라고 쓴 것처럼 합쳐져요. 문법에 주의하세요. translate: 10px 20px와 scale: 1.2는 함수 괄호 없이 값을 받아요.
translate(-50%, -50%)로 가운데 정렬
translate() 퍼센트는 요소 자신의 크기를 가리키기 때문에, top: 50%; left: 50%; transform: translate(-50%, -50%)는 크기와 상관없이 absolute로 배치한 요소를 부모 안에서 가운데 정렬해요. div 가운데 정렬 페이지에서 flexbox, grid와 비교해요.
자주 하는 실수
transform 선언 두 개. 나중 것이 완전히 이겨요. 함수를 합치거나 rotate, scale, translate 속성을 쓰세요.
인라인 요소에 transform. 그냥 <span>이나 <a>는 transform을 무시해요. inline-block으로 만드세요.
이웃이 움직일 거라고 기대하기. transform은 레이아웃을 절대 바꾸지 않아요. 공간을 만들려면 width, margin, gap을 바꾸세요.
잘못된 함수 순서.translate() 앞에 rotate()를 두면 회전한 축을 따라 움직여요.
position: fixed 자식의 뜻밖의 동작. transform된 요소는 fixed 자손의 포함 블록이 되어서, 그 안의 고정 헤더가 함께 스크롤돼요. z-index를 위한 새 쌓임 맥락도 만들어요.
자주 묻는 질문
CSS에서 transform은 무엇을 하나요?
요소가 그려지는 방식을 바꿔요. 옮기거나(translate), 크기를 바꾸거나(scale), 돌리거나(rotate), 기울여요(skew). 요소는 레이아웃에서 원래 자리를 유지해서 주변 요소가 움직이지 않아요.
CSS에서 transform을 여러 개 적용하려면 어떻게 하나요?
transform 값 하나에 공백으로 구분해서 나열하세요. transform: translateX(50px) rotate(20deg) scale(1.2); 두 번째 transform 선언을 쓰면 첫 번째에 더해지는 게 아니라 대체돼요.
transform 함수의 순서가 중요한가요?
네. 왼쪽에서 오른쪽으로 읽으면 각 함수는 앞선 함수들이 남긴 축에서 동작해요. 그래서 rotate(45deg) translateX(100px)는 회전한 축을 따라 요소를 옮기고, translateX(100px) rotate(45deg)는 똑바로 옮긴 다음 돌려요.
transform-origin은 무엇인가요?
크기 조절, 회전, 기울이기가 일어나는 고정점이에요. 기본값은 가운데(50% 50%)예요. transform-origin: top left는 요소를 왼쪽 위 모서리에서부터 키우거나 그 모서리를 중심으로 돌려요.
span에서 transform이 동작하지 않는 이유는 무엇인가요?
transform은 그냥 <span>이나 <a> 같은 비대체 인라인 요소에는 적용되지 않아요. 요소에 display: inline-block이나 block을 주면 transform이 동작해요.