본문으로 바로가기

CSS 2D 트랜스폼(Transforms)

category StyleSheet/CSS 2018. 12. 27. 11:04

transform(변형)은 CSS3에 추가된 기능 중 하나로 2D 의 변형을 말합니다.

변형이라는 것은 쉽게 말해서 특정 요소를 여러 가지 방법으로 모양을 바꾸는 것을 의미합니다.



일반적으로 변형(transform) 효과는 CSS transition(이동효과)와 함께 사용될 때, 또는 3D 기능들과 함께 사용될 때 진정한 효과가 나타납니다.

그렇지만 먼저 가장 기본적인 전환의 형태인 2D 전환에 대해서 이해해야 합니다.

이 챕터에서는 2D 변형(전환)에 대해 학습해 봅니다.




CSS3 transform - 2D 변형(전환)

transform 테크닉은 2D 환경의 X축, Y축에 대한 변형(전환)을 사용합니다.

이 변형 기술에는 다음과 같은 4가지가 있습니다.

  • rotate(회전 효과) : rotateX(), rotateY(), rotate(x, y)
  • scale(확대/축소 효과) : scaleX(), scaleY(), scale(x, y)
  • translate(이동효과) : translateX(), translateY(), translate(x, y)
  • skew(비틀기) 효과 : skewX(), skewY()

네 가지 주요 전환 함수들 외에 matrix() 함수가 있습니다. 모든 전환에 대해서 이에 상응하는 매트릭스가 존재하는데 이는 이해하기 상당히 복잡하고 어려울 수 있습니다.

matrix 는 다른 함수들의 기초가 되는 함수입니다.

그래서 matrix를 제대로 쓸 줄 알면 다른 transform 함수들을 조합해서 사용하는 것보다 간결하게 작성할 수 있습니다.
하지만 직관적이지 않기 때문에 사용하기 쉽지는 않습니다.

위의 네가지 함수는 rotate, translate, scale, skewmatrix 함수를 손쉽게 사용할 수 있도록 도와주는 함수들입니다.



rotate(회전)

rotate() 메서드는 각도(degree), 턴(turn)을 이용해서 지정할 수 있습니다.

회전의 각도가 양수이면 시계 방향으로 회전하고 음수이면 시계 반대방향으로 회전하게 됩니다.

See the Pen rotate 예제파일 by jaeheekim (@jaehee) on CodePen.


transform 은 2D 환경에서 변형 효과를 나타내기 때문에 rotateX(80deg); 만 적용했을 때 그 대상은 눕는 것처럼 보여지게 됩니다.
즉, 평면에서 찌그러트린 느낌이 들 것입니다.

하지만 추후 학습할 3D 환경에서의 소실점이 적용된 transform 을 사용하게 되면 좀 더 자연스러운 형태를 구현할 수 있습니다.

css
.object {transform: rotate(1.2turn);


scale(크기)

scale() 함수는 일정한 수치로 요소의 크기를 배가시켜서 그 크기를 조정할 수 있도록 합니다.

예를 들어서 scaleX() 의 값이 2(1은 100%를 의미)일 때 본래 너비가 200px인 요소는 너비가 400px로 변화게 됩니다.

짐작하겠지만 scale() 값이 1인 경우는 해당 요소의 본래 치수를 유지하고 그 이상의 값은 크기를 늘리게 되고 그 이하의 값은 크기를 줄이게 됩니다.

즉, scale() 함수는 1 값이 원래의 크기이고 0.5, 1.5 와 같은 배율로 지정할 수 있습니다.

그리고 단순히 이미지만을 확대/축소하는 것이 아니라, 부모 요소에 적용하면 하위요소까지 영역을 가지는 모든 요소를 확대/축소해 주기 때문에 페이지 전체의 확대나 축소에도 적용할 수 있습니다.

See the Pen zByVkB by jaeheekim (@jaehee) on CodePen.


scale() 함수는 이미지를 확대하거나 축소하기 때문에 보통은 이미지 갤러리 등에서 많이 사용됩니다.

예를 들어 마우스를 오버(hover)하면 이미지가 커지는 효과 등에 사용합니다.

사실 확대,축소 효과는 width, height 속성을 이용하여 나타낼 수도 있습니다.

하지만 width, height 를 이용할 때 보다 좋은 점은 무엇이 있을까요?

여러 좋은 점이 있을 수 있겠지만 그 중에 하나는 hover 의 경우를 들 수 있습니다.

예를 들어, 레이아웃 6개 박스가 2행 3열로 배치되어 있다고 가정해 봅니다. 이 때 박스가 hover 상태일 경우 너비와 높이가 1.5배를 크게 하려고 width, height 속성을 이용한다면 그 hover 상태의 박스 하나로 정렬이 틀어질지도 모릅니다.(물론 다른 방식을 사용하면 틀어지지 않도록 할 수 있지만.. 일반적 상황을 가정으로 들고 있음에 유의)

하지만 scale() 함수를 이용한다면 translate() 함수와 마찬가지로 다른 요소에 영향을 미치지 않기 때문에 좀 더 유용할 수 있습니다.

다시말해, width, height 속성을 사용하여 박스의 크기를 키울 경우 다른 박스들의 진로에 영향을 주게 되지만 scale() 함수는 다른 주변 박스들은 아무런 영향도 받지 않는 듯이 질서를 유지하고 크기가 커진 박스만 사용자 쪽으로 튀어나오는 것과 같은 효과를 만들어 냅니다.


만약 이 기법을 이미지 썸네일(thumnail) 갤러리(축소 이미지 갤러리)에서 hover 상태가 될 때 축소된 이미지가 커지도록 하는데 사용한다면 픽셀화 현상(이미지가 깨지는 현상)을 고려하여 처음부터 hover 이미지를 크게 제작한 후 처음 썸네일 이미지의 scale 값을 작게 축소하면 될 것입니다.

css
.gallery img {
    transform: scale(0.6);
}
.gallery img:hover {
    transform: scale(1);
}


translate(이동)

translate() 함수는 x축과 y축 상에서 해당 요소를 본래 위치로부터 움직여서 페이지의 다른 어딘가로 이동시키는 역할을 합니다.

예를 들어 수직과 수평상의 위치를 재조정할 때 이를 따로따로 수행할 수도 있고 또는 하나의 함수로 결합할 수도 있습니다.

정리하면, translate 효과는 원래의 위치를 기반으로 해서 이동하는 것을 의미하며, 중요한 것은 원래의 위치 정보는 남아있다는 사실입니다.

다음과 같은 데모에 이미지를 x 축으로 100px, y 축으로 100px 이동시키는 translate 를 살펴봅니다.

See the Pen translate 예제 by jaeheekim (@jaehee) on CodePen.

주의해서 봐야 하는 것은 원래 이미지를 담고 있던 테두리입니다.

본래 있어야 할 곳에 테두리가 있고 이동은 정해진 오프셋만큼 그 이후에 발생합니다.


css
.object {
    -ms-transform: translate(50px,100px); /* IE 9 */
   	-webkit-transform: translate(50px,100px); /* Safari */
    transform: translate(50px,100px);
}

#object-01 {
    width: 300px;
    height: 300px;
    background: blue;
    transform: translateX(100px) translate(50px);
}

#object-02 {
    width: 300px;
    height: 300px;
    background: red;
    transform: translate(10px, 80px);
}


translate 단위는 px, %, em 등을 사용합니다.

translate() 값이 하나만 있을 경우에는 가로 방향 이동만을 나타내며 세로 방향 이동은 없다고 간주해 버립니다.


translate 함수는 position 과 연관된 속성인 top, left, right, bottom 과는 어떻게 다른 것일까?

position 속성은 해당 요소를 컨테이너를 기준으로 움직입니다. 그에 반해서 translate() 는 언제나 해당 요소의 본래(자신) 위치를 기준으로 하여 새 위치를 잡게 됩니다.

게다가 position: absolute;가 적용된 요소는 레이아웃상의 다른 요소들과 완전히 별개의 존재가 되어 형제 요소들에게 어떤 영향도 미치지 않게 됩니다.

그러나 translate() 함수는 물리적으로 시야에 존재하는 한 해당 요소가 본래 차지하고 있던 공간을 그대로 유지하게 됩니다.


다음의 그림을 보면 8번 박스를 이동시켰음에도 본래 차지(그 공간을 사용하지 않더라도)하고 있던 공간(빨간 보더 공간)은 유지합니다.

이렇게 이동한 요소는 레이아웃의 다른 요소들과 별개의 독립적 존재가 됩니다.

position 속성값과 translate()는 이렇게 서로 방식이 다르기 대문에 상황에 따라서 다양하게 필요한 선택을 할 수 있습니다.

레이아웃 솔루션의 경우는 position: absolute; 가 좀 더 적합하고 hoveractive 같은 트리거 이벤트를 위해서는 translate() 가 좀 더 편리할 수 있다라고 감히 생각해 봅니다.


크롬 개발자이자 프론트 엔드 개발의 선두주자인 Paul Irish는 position 속성값과 translate(), 두 가지 방법을 사용한 애니메이션에 대해 다음과 같이 언급하고 있습니다.

top/left는 각 프레임을 그려내는 데 너무 많은 시간을 소요한다. 그 결과 약간 뚝뚝 끊어지는 듯이 전이가 이루어진다.
반면에 translate는 요소가 GPU(RenderLayer라고 불림)상에서 자기 자신의 레이어 위에 놓여지도록 만든다.....
GPU 상에서 그 자신의 레이어 위에 놓이기 때문에 2D 전환이 훨씬 더 빠르게 진행되고 프레임 속도도 빠르다.



skew(비틀기,기울기)

skew() 함수의 경우는 x축, y축을 기준으로 각도를 주어 모양을 변형시킵니다.

처음 skew 를 실행해 보면 예상한 것과 달리 실제 표현되는 것에 차이가 있을 수 있으니 연습이 필요할 지도 모르겠습니다.

다음의 예제를 살펴보도록 합니다.

See the Pen skew example by jaeheekim (@jaehee) on CodePen.

비틀기의 원리를 간단히 설명하도록 하겠습니다.

요소의 x축과 y축을 따라서 뼈대가 각각 하나씩 있다고 상상해 봅니다.

가로 방향으로 비틀면 x축은 가만히 있고 y축이 비튼 각도만큼 회전하게 됩니다.

다시 말해, skewX() 를 지정하면 y축이 회전하게 됩니다.

값이 양수면 시계 반대반향으로 회전(비틀게되고)하고 값이 음수면 시계 방향으로 회전(비튼다)하게 됩니다.

위 예제 skewX(15deg) 의 경우, 가로 방향으로 비틀면 x축(x선상)은 가만히 고정되어 있고 y축(y선상에 있는)이 시계 반대방향으로 회전하게 되어 박스가 위와 같이 기울여 보이게 되는 것이고, skewY(15deg) 의 경우도 마찬가지로 주어진 값만큼 x축이 회전하는데 즉, 세로 방향으로 비틀면 y축(y선상)은 고정되고 x축(x선상에 있는 선이)이 시계 반대방향으로 회전하게 되면서 위 처럼 기울어져 보이게 됩니다.


X축[좌/우] => 좌: -(마이너스)각도 / 우: +(플러스)각도...로 기울이는 효과

Y축[상/하] => 상: -(마이너스)각도 / 하: +(플러스)각도.. 로 기울이는 효과

정리해 보면,

skewX(x deg) : 각도가 양수인 경우 영역의 상단은 왼쪽 방향으로 영역 하단은 오른쪽 방향으로 비틀리고,

skewY(y deg) : 각도가 양수인 경우 영역의 좌측은 위로, 우측은 아래로 비틀리게 된다.


위의 내용이 이해하기 힘들다면 아래와 같이 이해하셔도 무방합니다.

X, Y 축을 기준으로 기울이게 되는데 X축은 좌/우로, Y축은 상/하로 기울이는 효과를 준다.

X 축에 +(플러스) 각도는 우측으로 , -(마이너스) 각도는 좌측으로 기울이는 효과이며,

Y 축에 +(플러스) 각도는 아래쪽으로, -(마이너스) 각도는 윗쪽으로 기울이는 효과를 준다.



transform-origin(기준점 설정)

앞서 학습한 내용들을 살펴보았다면 위 기능들은 해당 요소의 중심을 기점으로 동작한다는 것을 확인했을 것입니다.

예를 들어 scale 이 적용된 요소는 그 중심을 기점으로 크기가 커지고 rotate 가 적용된 요소들은 요소의 중심점을 기준으로 회전을 하게 됩니다.

하지만 transform-origin 속성은 전환이 발생하는 기준점을 x와 y 매개변수로 명시하여 중심이 아닌 다른 지점을 지정할 수 있는 속성입니다.

See the Pen skew 기준점 bottom by jaeheekim (@jaehee) on CodePen.

위의 예제는 기준점을 요소의 바닥으로 옮겨서 아랫 면은 고정된 채로 오른쪽으로만 기울게 됩니다.


transform-origin 속성값은 다음과 같습니다.

  • x축 : left, center, right, length, %
  • y축 : top, center, bottom, length, %
  • z축 : length, view 가 z축에 배치되는 곳을 지정한다(3D 변환(transition)과 함께 사용될 경우)


transform 여러 효과를 함께 사용하기

translate, rotate, scale, skew 효과를 하나로 묶어서 사용할 수가 있습니다.

아래 예제 코드와 같이 공백을 구분자로 하여 각 함수를 나란히 작성할 수 있으며, 효과는 차례대로 나타내게 됩니다.

See the Pen 트랜스폼 믹스사용하기 by jaeheekim (@jaehee) on CodePen.



View complete example

See the Pen CSS3 Transform Test by jaeheekim (@jaehee) on CodePen.





Jaehee's WebClub