본문으로 바로가기

CSS3 transform - 2D 전환

category StyleSheet/CSS 2016. 9. 29. 08:23

CSS3 2D transform(전환)

transform(변형)은 CSS3에 추가된 강력한 기능입니다.

지난 몇 년사이에 웹에서 CSS와 연관된 것 중 감탄할 만한 새로운 시도들을 발견했다면 그 기저에는 transform(변형)이 있을 확률이 높습니다.

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

전환의 진정한 잠재력은 CSS transition(이동효과)와 함께 사용될 때, 또는 3D 기능들과 함께 사용될 때 완전하게 표현됩니다.

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

지금부터 2D 전환에 대해 알아봅니다.



2D 전환만으로도 요소의 위치, 크기, 방향, 원근 등을 의도대로 조정할 수 있고 이 모든 것이 한 줄의 CSS로 가능합니다.



transform 속성

transform 속성은 많은 함수들을 수용하지만 2D 조건하에서는 다음의 네 가지 함수가 주를 이룹니다.

  • translate()
  • skewX(), skewY()
  • rotate()
  • scale()

rotate() 함수를 제외한 각 함수는 두 개의 매개변수를 수용합니다.

즉, 각 차원(dimention)당 값이 하나씩 오게 됩니다. 

2D 환경에서 차원(dimention)이란 가로 x축과 세로 y툭에 해당하는 각각의 값을 말합니다. 이 부분에 대해서는 translate() 함수를 다룰 때 다시 다루게 될 것입니다.


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

매트릭스 함수의 활용에 대해 알고자 한다면 다음의 오페라 개발자 사이트를 참고하기 바랍니다.


transform 지원 현황

 

 

 

 

 IE10

36.0 

16.0

9.0 

23.0 

  • prefix를 이용하여 Chrome 4.0 - webkit-, IE9 -ms-, FF 3.5 -moz-, safari 3.2 -webkit-, opera 10.5 -o- 를 이용해 지원할 수 있다. 



Translate(이동)

translate() 는 어떤 동작을 할까?

단어 이름이 translate이지만 의미론적인 뜻과는 아무런 상관이 없고 이 함수는 x축과 y축 상에서 해당 요소를 본래 위치로부터 움직여서 페이지의 다른 어딘가로 이동시키는 역할을 합니다.

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

다음의 코드를 참고하도록 합니다.

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

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

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

만약 #demo-02 에 작성된 매개변수가 하나만 존재한다면 y축은 0의 값을 받고 주어진 값을 x축의 값으로 적용됩니다.

w3c TEST VIEW


그렇다면 이 속성은 기본의 position 속성값인 top, left, right, bottom 과는 어떻게 다른 것일까?

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

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

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

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


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


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

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

그러나 이것은 일반적인 규칙이고 각자의 상황을 고려하여 결정해야 할 것입니다.


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

top/left는 각 프레임을 그려내는 데 너무 많은 시간을 소요한다. 그 결과 약간 뚝뚝 끊어지는 듯이 전이가 이루어진다. 

반면에 translate는 요소가 GPU(RenderLayer라고 불림)상에서 자기 자신의 레이어 위에 놓여지도록 만든다...... GPU 상에서 그 자신의 레이어 위에 놓이기 때문에 2D 전환이 훨씬 더 빠르게 진행되고 프레임 속도도 빠르다.




Skew(기울이기)

skew() 함수는 활용할 만한 범주가 제한적이라서 다양한 전환 함수들 중에서 그다지 관심을 받지 못했습니다.

어쩌면 우리가 충분히 창의적으로 생각을 하지 않았기 때문일 수도 있습니다. 그러나 이 함수 역시 분명 그 용도를 갖고 있고 애니메이션을 만들 때 인상적인 효과를 만들어 낼 수 있습니다.

현재 skewX(), skewY()가 아닌 skew() 함수를 구현하고 있는 경우에도 오래 전에 제작된 콘텐츠들에 대한 호환성을 유지하기 위해서 이를 지원하고 있지만, skew() 이 함수 자체는 사실상 사라지게 되었습니다.

대신 skewX() 와 skewY() 함수를 사용하여 별도로 x와 y 기울기를 명시하도록 해야 합니다. x와 y 값을 skew() 함수 안에 한데 결합하여 사용하면 전혀 다른 결과가 나올 수도 있기 때문입니다.

그렇다면 skew 전환은 실제로 어떤 일을 하게 될까?

간단히 말해서 이것은 기본적으로 축을 기준으로 요소를 회전시켜서 기울어지게 만듭니다.

css
.skewX {
    -ms-transform: skewX(20deg); /* IE 9 */
    -webkit-transform: skewX(20deg); /* Safari */
    transform: skewX(20deg);
}

.skewY {
    -ms-transform: skewY(20deg); /* IE 9 */
    -webkit-transform: skewY(20deg); /* Safari */
    transform: skewY(20deg);
}



See the Pen skew 테스트 by jaeheekim (@jaehee) on CodePen.


skew 전환은 해당 요소의 관점을 변화시키고 이미지를 의지하지 않고 추상적인 모양들을 만들어 낼 수 있다는 측면에서 그 자체만으로도 쓸모가 있다.  그러나 대부분의 다른 전환 함수들과 마찬가지로 애니메이션화될 때 그 빛을 발하기 시작한다.




Rotate(회전)

rotate() 함수도 매우 강력한 기능을 갖고 있으며 과거에 이미지나 자바스크립트를 통해서 수없이 많이 활용되었기 때문에 중요성을 의심할 여지가 없을 것입니다.

skew() 전환과 마친가지로 rotate() 함수도 각도 기반의 값으로 동작합니다. 그러나 다른 2D 전환 유형들은 x축과 y축으로 수평과 수직을 따라 적용되지만 2D 환경에서 rotation은 z축과 관련이 있습니다.

css
#demo-01 {
    -ms-transform: rotate(-90deg); /* IE 9 */
    -webkit-transform: rotate(-90deg); /* Safari */
    transform: rotate(-90deg); /* 반시계 방향 */
}

#demo-02 {
    -ms-transform: rotate(90deg); /* IE 9 */
    -webkit-transform: rotate(90deg); /* Safari */
    transform: rotate(90deg); /* 시계 방향 */
}

w3c TEST VIEW


결론적으로 rotate() 함수는 애니메이션과 함께 사용될 때 훨씬 더 강력한 능력을 발휘한다.



Scale(스케일)

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

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

css
div {
    -ms-transform: scale(2,3); /* IE 9 */
    -webkit-transform: scale(2,3); /* Safari */
    transform: scale(2,3);
}
.demo {
    transform: scaleX(2) scaleY(3);
}


만약 하나의 매개변수가 가진 scale() 함수를 사용할 경우 값이 하나 생략된 것으로 간주하되 생략된 변수에 0을 적용하는 것이 아니라 명시된 하나의 값을 x와 y 둘 모두에 적용을 하게 됩니다.

css
div {
    transform: scale(2);
    /* 하나의 매개 변수가 x축과 y축 모두에 적용된다 */
}

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

그리고 translate() 함수를 position 속성값과 비교했 듯이 scale() 함수는 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);
}

이렇게 하면 이미지가 처음 크기 또는 그 이하로 유지되는 한 이미지가 깨질 염려는 없을 것입니다.


scale() 함수는 :hover와 같은 트리거 이벤트에 적용될 때 보다 더 중요한 역할을 하게 된다.




transform-origin 속성

지금까지 설명한 내용들을 살펴보았다면 위 기능들은 해당 요소의 중심을 기점으로 동작한다는 것을 확인했을 것입니다.

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

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

css
div {
    -ms-transform: rotate(45deg); /* IE 9 */
    -ms-transform-origin: 20% 40%; /* IE 9 */
    -webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
    -webkit-transform-origin: 20% 40%; /* Chrome, Safari, Opera */
    transform: rotate(45deg);
    transform-origin: 20% 40%;
}


CSS Sytax

transform-origin: x-axis y-axis z-axis | initial | inherit;

  • x축 : left, center, right, length, %
  • y축 : top, center, bottom, length, %
  • z축 : length, view 가 z축에 배치되는 곳을 지정한다(3D 변환(transition)과 함께 사용될 경우)
  • initial : 이 속성의 기본값을 따릅니다.
  • inherit : 부모 요소로부터 값을 상속 받습니다.

w3c TEST VIEW




전환(transform)을 복합적으로 결합하기

앞서 언급했던 전환 함수 여러가지를 결합하여 효과들을 보다 폭넓게 활용할 수 있습니다.

다음의 코드를 살펴보기 바랍니다.

See the Pen combining-transforms test by jaeheekim (@jaehee) on CodePen.






Jaehee's WebClub