3D 트랜스폼(Transforms)
CSS 변형(2D transform)은 좌표공간을 변형함으로써 일반적인 문서 흐름을 방해하지 않고 콘텐츠의 형태와 위치를 바꿉니다.
즉, 변형으로써 이동을 시키거나 크기, 회전, 비틀림을 제어하는 경우에 사용했으며 어디까지나 이 트랜스폼은 X축, Y축 좌표만을 조정할 수 있는 2D 였습니다.
이 2D에서 더 나아가 3D에 관련된 CSS 속성을 알아보도록 하겠습니다.
3D transform을 위한 속성
3D 공간에서의 CSS 변환은 좀 더 복잡합니다.
CSS 3D transform 은 평면에서의 여러 개 CSS 속성을 조합하고 3D 공간에서의 회전, 확대, 이동, 비틀기를 포함하고 원근감, 관찰자의 위치을 부여해 3D 공간을 만들어 낼 수 있습니다.
그리 3D transform 은 크게 트랜스폼을 적용할 요소에 적용하는 속성과 자식 요소를 3D로 처리하기 위해 부모 요소에 설정하기 위한 속성이 있습니다.
트랜스폼을 적용할 요소에 적용하는 속성
- transform-origin : 회전을 시킬 축을 결정, 기본값은
transform-origin: 50% 50%;
- backface-visibility :입체적인 뒷면의 가시성을 결정하는 속성,
즉, 변형이 가해져서 요소의 뒷면(뒤집힌 것)을 숨기거나 보여지게 할 수 있습니다. - rotateX()
- rotateY()
- rotateZ() = rotate()
- rotate3d(x, y, z)
- translateX()
- translateY()
- translateZ() = translate()
- translate3d(x, y, z)
- scaleX()
- scaleY()
- scaleZ() = scale()
- scale3d(x, y, z)
- skewX() : skew 는 skewZ() 인 Z축이 없으며 사실 3D가 아닙니다.(생동감만 부여할 뿐..)
- skewY()
- skew()
- perspective : 원근, 소실점, 투시도법(가까이 있는 사물은 커보이고 멀리 있는 사물은 작아보이는 것)
예를 들어, 평면에서 입체적으로 보여주기 위해 건축도면(설계도) 등에서 투시도법을 많이 사용함.
자식 요소를 3D 처리하기 위한 부모 요소에 설정하기 위한 속성
- perspective : 원근, 소실점, 투시도법
- perspective-origin : 원근법에 대한 기준점을 설정
- transform-style: preserve-3d : 요소의 자식이 3D 공간에 배치
3D transform 살펴보기
See the Pen 3D transform 예제 by jaeheekim (@jaehee) on CodePen.
3D 환경을 위한 perspective(투영점, 원근, 소실점, 투시도법)
3D 효과를 표현하기 위해서는 2D 효과인 transform, transition 등에 3D 를 위한 속성을 설정하고 가장 중요한 투영점(perspective)을 지정 하는 것입니다.
3D 효과를 이해하기 위해 다음의 x축, y축, z축에 대한 그림을 참고하기 바랍니다.
3D 공간을 구성하기 위해서는 소실점(투영점, 원근감)을 지정해야 합니다.
그렇지 않으면 의도한 3D 효과가 나타나지 않고 평면으로 보이게 될 것입니다.
Perspective
속성은 원근감을 표시할 수 있도록 관찰자 시점(위치)의 거리를 지정하는 속성으로 Z 인덱스와 관찰자 사이의 거리에 영향을줌으로써 요소에 3D 공간을 제공합니다.
즉, Perspective 평면(z = 0)과 사용자(관찰자) 사이의 거리를 결정합니다.
z > 0인 각 3D 요소가 커지고, z < 0 인 각 3D 요소는 더 작아집니다.
효과의 강도는 이 perspective 속성값이 커질수록 왜곡이 적어지게 됩니다. 즉, 관찰자 위치가 가까이서 본 형태의 3d 로 나타나게됩니다.
Perspective
속성값은 다음과 같습니다.
- none : 원근감 변환을 적용하지 않아야 함을 나타내는 키워드입니다.
- length : 사용자로부터 평면(z = 0)까지의 거리를 나타냅니다. 요소와 내용에 원근감 변환을 적용하는 데 사용됩니다.
0 또는 음수 값이면 원근감 변환이 적용되지 않습니다.
perspective(투영점)은 3D 원근감을 주는 초점이라고 할 수 있습니다.
투영점이라는 단어는 사진을 다루는 사람들에게 익숙할 지도 모르겠으나 이 용어는 관찰자 관점(viewing perspective), 원근감 등의 용어와도 비슷한 의미로 받아들일 수 있습니다.
즉, 3D 환경을 만들기 위해서 사용자는 관찰자 지점, 즉 투영점(깊이감,원근감)을 구체화시켜야 하며, 이것이 입체감을 부여하게 됩니다.
기본적으로 보는 사람의 위치를 추정하여 이 투영점을 명시함으로서 3D 환경의 관점을 설정하는 것입니다.
그리고 이 속성은 픽셀 기반의 길이 값을 지정할 수 있으며 z축을 따라 평면으로부터 관찰자의 거리(깊이감)을 나타내게 됩니다.
그래서 perspective:300px;
은 300px 만큼 떨어진 곳(즉, z축을 따라 300px)에 관찰자가 있다는 것을 근거로 하여 3D 환경을 구성하게 됩니다.
만약 이 perspective
속성인 투영점(또는 관찰자 관점,원근감,깊이감)이라는 개념이 어렵다면, 기본적으로 멀리 떨어져 있어야 하는 사물은 작게 만들고 가까운 곳에 있어야 하는 사물은 크게
만들어서 원근감을 부여하는 것으로 이해하셔도 무방합니다.
perspective 기본 예제
See the Pen 3D 투영점 설정 #1 by jaeheekim (@jaehee) on CodePen.
첫 번째 박스에는 아무런 효과도 없는 기본 박스이고 두 번째 박스에는 rotateX(45deg) 를 적용한 박스입니다.
2D 에서 X축 회전을 시킨 것이기 때문에 박스가 찌그러진 것처럼 보이는 것입니다.
세 번째 박스에 소실점을 지정하기 위해 부모에 transform-style: preserve-3d; perspective: 300px;
이와 같이 선언하였습니다.
이 속성으로 인해 이 요소는 3차원의 객체로 변환되어 3D 공간과 같은 깊이감을 나타내게 됩니다.
위 예제에서는 transform
이라는 속성을 이용하여 rotateX 를 선언한 것에 주목해야 합니다.
transform 이라는 속성(용어)은 3D 효과에서 모양 자체의 변형이 있기 때문에 만들어진 용어입니다.
위 설정에서 rotateX 를 x축을 기준으로 하여 45도 회전하고 소실점 깊이를 300px 을 선언하여, 300px 만큼 떨어진 위치(관찰자 위치)에서 wrapper 영역을 바라보고 있다고 할 수 있습니다.
일반적으로 관찰자 시점이 적용될 요소는 해당 요소가 아닌 변형되는 요소를 포함하고 있는 부모 요소에 원근감을 설정해야만 한다는 것입니다.
즉, 변형시킬 요소의 부모에 적용하는 것이며 해당 부모의 모든 자식들이 동일한 관점으로 동일한 3D 공간에서 동작하게 되는 것입니다.
그러나 부모 요소가 아닌 변형시키는 해당 요소에만 3D 전환을 적용하고 싶다면 그렇게 할 수도 있습니다.
해당 요소에만 3D를 적용하려면 소실점(깊이감)에 대한 값을 아래의 코드와 같이 다르게 적용할 수 있습니다.
See the Pen 투영점(perspective) #2 by jaeheekim (@jaehee) on CodePen.
다음은 소실점과 트랜스폼을 적용했을 때 이해를 돕기 위한 이미지입니다.
부모 요소의 소실점 VS 변형시킬 대상 요소의 소실점
앞서 살펴본 예제 중 하나는 부모인 컨테이너에 소실점을 적용한 것이고 또 다른 하나는 변형시킬 대상 요소에 투영점을 반영한 것입니다.
위 예제에서는 별다른 차이점을 느끼지 못했을 테지만 컨테이너인 부모요소에 perspective 속성을 사용하는 것과 변형 대상 요소에 이 속성을 사용하는 것은 근본적으로 다른 결과를 만들어 냅니다.
특히 3D 변형이 적용된 요소가 형제 요소들을 가지고 있을 때 다른 결과를 낳게 됩니다.
다음 코드는 컨테이너인 부모 요소에 perspective 속성을 정의한 것과 개별 요소들에게 각각 perspective() 함수를 적용한 것에 대한 예제입니다.
See the Pen 투영점 설정 #3 by jaeheekim (@jaehee) on CodePen.
위 결과를 살펴보면 부모에 투영점이 적용되었을 경우와 대상요소에 적용되었을 때의 결과가 다르게 나타납니다.
특히 부모 요소에 투영점이 반영된 형제 요소의 변형(transform)이 개별요소가 아니라 원근감을 서로 간에 영향을 미치면서 반영되는 것을 확인할 수 있습니다.
perspective & translate
지금까지는 회전을 시키고 소실점을 반영했으나 이번에는 translate 로 이동을 시키고 3D 효과가 어떻게 동작하는지 살펴보도록 합니다.
다음 코드는 z축으로 150px 만큼 이동하고 부모요소에 소실점을 반영한 예제입니다.
See the Pen 화면이동과 투영점 by jaeheekim (@jaehee) on CodePen.
만약에 요소를 움직일 때 perspective
값을 명시하지 않고 z축을 따라 100px 을 이동시킨다면 당연히 요소에 어떠한 시각적인 변화도 일어나지 않습니다.
다시 말해 z축을 따라 100px 만큼 움직이지만 거리를 가늠할 관점이 없기 때문에 분명하게 드러나지 않는 것입니다.
그래서 3D 환경을 구성하기 위해 컨테이너 요소에 perspective
를 선언하면 위와 같은 결과가 나타나게 됩니다.
위의 결과는 요소가 관찰자와 가까운 쪽으로 움직이면서 요소의 크기가 커지고 있습니다.
이는 translateZ()
함수와 perspective
속성은 동일한 축에서 동작한다는 것을 이해해야 합니다.
위 그림의 Z축이 관찰자 시점과 동일한 선상에 있다고 이해하면 됩니다.
예제에서 소실점 반영이 500px 만큼 떨어진 관찰자 시점에서 요소가 150px 만큼 Z축을 따라 옮겨진 것이기 때문에 앞으로 튀어나온 것과 같은 시각적인 효과가 나타나게 되는 것입니다.
만약에 소실점 설정이 위와 같이 즉, perspective 속성이 스크린으로부터 500px 떨어진 곳에 관찰자의 위치가 설정되어 있으면서 대상 요소에 대한 Z축이 600px 만큼 이동한다면 그 요소는 "관찰자 시점의 뒤편"으로 위치하기 때문에 보이지 않을 것입니다.
소실점과 트랜스폼 속성 적용 순서에 따른 효과
지금까지 회전과 Z축에 대한 투영점에 대한 효과를 각각 알아보았으며 이제는 투영점이 있는 상태에서 각도를 회전(rotate)하고 이동(translate)을 동시에 적용할 경우의 효과에 대해 알아보도록 하겠습니다.
이 회전과 이동을 동시에 적용하면서 투영점을 반영할 경우에는 상당히 다른 결과가 나타나는데 재미있는 사실은 회전을 하고 이동하는 것이냐 아니면 이동을 하고 회전하는 것이냐에 따라 상당히 다른 결과차이를 보인다는 것입니다.
다음 코드는 Y축으로 이동을 시킨 후 회전을 시킨 예제입니다.
See the Pen 화면이동과 투영점 #1 by jaeheekim (@jaehee) on CodePen.
위 코드 결과를 확인해 보면 Y축으로 200px 만큼 이동하고 나서 회전을 하게 됩니다.
시각적인 효과는 이동하면서 회전하듯이 아니면 회전하면서 이동하는 것처럼 보이지만 실제로는 이동을 한 후 회전을 하게 되는 것입니다.
즉, 코드에 선언한 순서대로 동작하게 됩니다.
앞선 예제를 이해하는데 무리가 없을지 모르나 다음 예제를 확인해 보면 갸우뚱 거릴지도 모르겠습니다.
다음 코드는 앞선 예제와 같은 효과이지만 변형 효과를 위와는 반대로 먼저 회전을 시키고 Y축으로 이동하는 예제입니다.
See the Pen 화면 이동과 투영점 #2 by jaeheekim (@jaehee) on CodePen.
위의 결과를 확인해 보면 단지 이동과 회전의 선언 순서만을 바꾸었을 뿐인데 완전히 다른 효과가 나타납니다.
이는 먼저 45도 각도로 회전을 한 후에 그 회전 축을 기점으로 Y축으로 200px 만큼 이동한 것이기 때문에 이와 같은 효과가 나타나는 것 입니다.
이해를 위해 다음의 그림을 참고하세요.
앞선 예제에서 45도의 회전 상태에서 소실점을 반영해 보고 앞서 살펴본 Z축을 따라 이동하면 어떠한 결과가 나타나는지 살펴보도록 하겠습니다.
See the Pen pbmroq by jaeheekim (@jaehee) on CodePen.
위 결과는 먼저 45도 회전한 상태에서 앞뒤로 움직이는 Z축 설정을 적용하였기 때문에 화면에서 앞으로 튀어나오는 것과 같은 효과가 나타납니다.
참고로 위의 Z축에 대한 이해를 하셨다면 바로 위 예제에서 이동에 대한 Z축을 Y축으로 변경하면 perspective
인 투영점을 반영하지 않았던 결과와 다를 것이 없다는 것을 이해하실 수 있을
것입니다.
backface-visibility(이면가시성)
뒤집어 진 것을 보여주거나 감출 수 있는 backface-visibility
속성에 대해 알아봅니다.
backface-visibility
속성은 3D 변형과 연관되어 있으며 입체적인 뒷면의 가시성(뒤집어진 면)을 결정하는 속성입니다.
즉, 변형이 가해져서 요소가 뒤집어 졌을 때, 이 속성으로 숨기거나 보여지게 할 수 있습니다.
backface-visibility
속성값은 다음과 같습니다.
- visible : 기본값으로 이면(뒷면)을 보여준다.
- hidden : 뒤집어진 면을 숨긴다.
backface-visibility 예제
See the Pen backface-visibility by jaeheekim (@jaehee) on CodePen.
image & box contents flip 예제
See the Pen CSS3 image flip (마우스오버) by jaeheekim (@jaehee) on CodePen.