Jaa


CSS를 통한 전체 페이지 애니메이션 구현

Internet Explorer 9는 CSS 2D 변환을 지원했습니다. 그리고 Internet Explorer 10 Developer Preview에서는 CSS 3D 변환CSS 애니메이션에 대한 지원이 추가되었습니다. IE10은 GPU 성능을 활용하고 일반적인 JavaScript를 비동기식으로 실행함으로써 웹 콘텐츠의 스크립트 기반 애니메이션이 보다 유연하고 뛰어난 성능으로 구현되도록 합니다.

이전 블로그 글에서는 CSS 3D 변환CSS 애니메이션 및 전환에 대해 다루었습니다. 이 글에서는 브라우징에 유연성과 연속성을 부여할 수 있도록 탐색 프로세스에 사용 가능한 "전체 페이지 애니메이션"의 개념에 대해 설명하고, 이 기술로 구현한 '차별화된' 활용 사례를 소개하고자 합니다. 우리의 목표는 사용자가 링크를 클릭하거나 관련 기능을 실행하여 페이지를 방문하고 화면 전환을 할 때 좀 더 자연스러운 브라우징 경험을 할 수 있도록 하는 것입니다.

이러한 효과는 CSS 애니메이션을 사용하는 HTML <body> 요소를 변환하여 간단하게 구현할 수 있습니다. 하지만 이 활용 사례는 <body>를 변환할 때의 레이아웃과 크기 조정의 효과, 그리고 애니메이션과 원활하게 맞물리도록 페이지 탐색 시간을 적절하게 조정하는 방법 등 논의가 필요한 몇 가지 고려 사항들을 보여줍니다.

다른 브라우저에서는 CSS 애니메이션과 CSS 변환 속성을 사용하기 위해 공급업체 접두사가 필요하지만 이 글에서 제시한 코드 샘플은 IE10 Release Preview에서 지원하는 접두사를 사용하지 않는 CSS 마크업을 사용합니다.

페이지의 전체 콘텐츠 변환하기

CSS 변환은 HTML DOM 요소의 스타일 속성에서 정의되어 있습니다. 예를 들어, 하나의 요소를 Z축을 따라 45도 각도로 회전시키는 마크업은 다음과 같습니다.

#element {

transform: rotateZ(45deg);

}

변환을 HTML 문서의 <body> 요소에 연결해도 정확히 같은 작용을 합니다. 따라서 문서의 <body>에 동일한 효과를 선언적으로 추가할 때에는 다음과 같이 할 수 있습니다.

body {

transform: rotateZ(45deg);

}

body 요소에 변환을 적용할 때 이전과 이후 스크린샷은 다음과 같습니다.

문서의 body 요소에 rotateZ(45deg) 변환의 적용을 보여주는 스크린샷
문서의 body 요소에 rotateZ(45deg) 변환 적용하기

3D 변환의 경우 CSS 변환 사양은 perspective 속성을 정의하며, 변환할 요소의 상위 영역에서 이 속성을 지정할 수 있습니다. 콘텐츠의 <body> 요소를 변환할 때는 DOM 계층에서 그 위에 있는 <html> 요소에 적용하여야 합니다. 그 과정은 간단합니다.

html {

perspective: 500px;

}

<body> 요소에서 이것을 rotateY(45deg) 변환과 결합하여 다음과 같은 결과를 얻을 수 있습니다.

원근법을 이용하여 <body>에 rotateY(45deg) 변환을 적용하는 것을 보여주는 스크린샷 <html>에 설정된 500px
원근법을 이용하여 <body>에 rotate(45deg) 변환 적용하기 <html>에 설정된 500px

body 요소에서 transform-origin 속성을 조작하면 흥미로운 결과를 얻을 수 있습니다. 그럼, 몇 가지 예를 살펴보겠습니다.

body {

transform-origin: 50% 100%;

transform: rotateX(45deg);

}

위의 마크업은 transform-origin을 사용하여 회전의 원점을 요소의 아래로 이동시키는 동안에 body 요소에 대해 X축을 따라 회전을 설정합니다. 문서의 콘텐츠를 다음과 같이 화면 "안쪽에" 효과적으로 회전시킵니다.

변환 적용을 보여주는 스크린샷 rotateX(45deg) 및 변형 원점: <body>에 50% 100%

축 분리 투사 효과를 구현하기 위해 문서의 루트 요소에 대한 perspective-origin 속성을 조작할 수 있습니다. <html>에 대한 스타일 변경:

html {

perspective: 500px;

perspective-origin: 90% 50%;

}

이제 페이지는 다음과 같이 보입니다.

원근법 적용을 보여주는 스크린샷 500px 및 원근법 원점: <html> 요소에 90% 50%

CSS 변환을 사용하여 페이지에 있는 콘텐츠 전체의 외관을 쉽게 조작할 수 있습니다. 아직까지는 통상적인 레이아웃과 크기 조정 규칙이 적용되기 때문에 body 요소상(특히 비율 값을 사용하거나 transform-origin 속성에 의존하는)의 변환은 페이지 콘텐츠에 따라 다소 상이한 시각적 효과를 발생시킬 수도 있습니다. transform-origin50% 100%로 설정된 이전의 rotateX(45deg) 예제를 생각해 보십시오.

아래에서 변환이 적용되기 전과 후의 결과를 볼 수 있습니다.

원근법 투사에 따라 변환을 적용하기 전후의 스크롤바의 차이점을 강조하는 스크린샷

콘텐츠가 실제로 창 하단에서 선회하지 않고 뷰포트 외부의 어느 지점에서 선회합니다. 다음은 CSS 변환에 대한 예상 동작입니다. <body>가 정상적으로 배치되고 콘텐츠는 화면에서 떨어진 어느 아래쪽의 가장자리를 따라 회전합니다. 변환된 콘텐츠를 수용하기 위해 (원근법 투사를 사용함으로써 이러한 효과가 더욱 확연해지며) 콘텐츠의 실제 공간이 확장되는 것을 확인할 수 있습니다("변환 적용 후" 사진의 스크롤 막대를 주목).

그럼 body 요소에 변환을 적용할 때 크기가 임의로 설정된 콘텐츠는 어떻게 처리할 수 있을까요? 일정량 이상 body의 크기가 확장되지 않도록 모든 콘텐츠에 따라 사용자 지정을 하는 것은 비현실적입니다. 대신에, 간단한 HTML/CSS 패턴을 사용하여 래퍼 <div>안의 브라우저 창과 추가 콘텐츠의 크기에 맞게 body 요소의 크기를 고정할 수 있습니다. 마크업은 다음과 같이 구현합니다.

html, body {

width: 100%;

height: 100%;

min-width: 100%;

max-width: 100%;

padding: 0;

margin: 0;

overflow: hidden;

}

 

#Wrapper {

position: absolute;

width: 100%;

height: 100%;

overflow: scroll;

}

아래의 그림은 페이지가 수직으로 스크롤되고 문서의 <body> 요소에 직접 rotateY(45deg) 변환을 적용할 때(좌)와 래퍼 패턴을 사용할 때(우) 어떠한 일이 발생하는지 보여줍니다.

원근법 투사에서 래퍼 CSS/HTML 패턴을 사용하거나 사용하지 않고 페이지가 수직으로 스크롤되고 rotateY(45deg) 변환이 <body>에 적용될 때 어떤 일이 발생하는지 보여주는 스크린샷

변환의 직접적인 응용은 축 분리 투사(더 이상 body 요소의 "중앙"을 보는 것은 아니므로)로 인해 기울어져 보이게 됩니다. 래퍼 패턴을 사용함으로써 <html> 요소의 perspective-origin 속성(50% 50% 기본값)은 <body> 요소에 대해 항상 정확히 중앙에 위치하게 되어 만족스러운 시각적 효과를 제공합니다.

언제든지 위의 패턴을 활용하고 비율 값으로 CSS 변환을 설정하면 콘텐츠의 크기와 상관없이 <body> 요소에 일관된 영향을 미칠 수 있습니다.

변환부터 애니메이션까지

CSS 변환을 <body> 요소에 적용하는 복잡한 메커니즘을 해결한 후에 진행해야 할 다음 단계는 CSS 애니메이션입니다. 위에서 언급한 원칙을 따라 놀라운 방법으로 웹 콘텐츠를 불러오는 애니메이션을 만들 수 있습니다.

아래의 기본적인 @keyframes 규칙을 살펴보시기 바랍니다.

@keyframes rotateInLeft {

from {

transform-origin: 0% 0%;

transform: rotateY(180deg);

}

to {

transform-origin: 0% 0%;

transform: rotateY(0deg);

}

}

이 애니메이션은 요소에 적용했을 때 좌측으로 회전하게 됩니다. 래퍼 패턴을 사용하는 <body> 요소를 적용하면 보다 흥미로운 시각적 효과를 얻을 수 있습니다. 문서는 사실상 브라우저 창에서 보여지는 영역의 으로부터 전체 화면으로 회전하게 됩니다.

유사한 방법으로 웹 콘텐츠를 부드럽게 제거하는 애니메이션을 구성할 수도 있습니다. 예를 들어 회전하는 동안 페이지를 멀리 사라지게 하려면 다음과 같이 할 수도 있습니다.

@keyframes whirlOut {

to {

transform: scale(0)rotateZ(1260deg);

}

}

시각적 결과와 함께:

웹 콘텐츠 전체에 영향을 미치는 CSS 애니메이션의 성능을 최대한 활용함으로써 이러한 페이지 효과를 생성할 때 보다 많은 유연성을 가질 수 있습니다. (물론 CSS 변환을 사용하는 것에만 한정되지 않습니다.) 만약 콘텐츠에 적용하고자 하는 효과를 구성하게 된다면 페이지 탐색 프로세스에서 어떻게 그 효과를 트리거할 수 있을까요?

<body>에 애니메이션 연결하기

우리의 목표는 페이지가 로드할 때 콘텐츠 전환의 모습을 보여주고, 사용자가 링크를 클릭할 때 숨겨지도록 브라우저를 경험하는 동안 전략적으로 트리거 애니메이션을 사용하는 것입니다.

body 요소에 애니메이션을 추가할 수 있는 가장 직관적인 곳은 onload JavaScript 이벤트입니다. 그러나 알려진 바에 따르면 onload가 발생할 때 실제로 애니메이션을 추가하는 과정은 매우 느리게 진행됩니다. 이런 경우는 콘텐츠 전체가 로딩(특정 이미지 또는 대역폭 집약적 리소스)을 마쳤을 때 발생합니다. 대역폭 집약적인 페이지상에서 onload에 애니메이션을 연결하면 콘텐츠가 "정상적으로" 나타나며 애니메이션을 트리거하고 콘텐츠를 화면에 다시 불러옵니다. 당초 예상했던 효과와는 사뭇 다르게 나타난 것을 확인할 수 있습니다.

대신 콘텐츠의 DOM 구조의 구문 분석이 완료될 때 트리거하는 DOMContentLoaded 이벤트를 활용할 수도 있습니다. IE 테스트 DOMContentLoaded 데모는 이 두 이벤트 간의 차이점을 보여줍니다. 그러나 복잡한 웹 콘텐츠의 경우 최신 브라우저는 DOM 트리 전체가 로드되기 전의 페이지를 보여주며 "진보적인" 렌더링을 수행하도록 선택할 수 있습니다. 이런 상황에서는 시각적 결과는 onload 시나리오에 가깝다고 볼 수 있습니다.

페이지 콘텐츠를 전환하는 애니메이션에 대한 최적의 설정 장소는 <body> 요소 맨 위에 있는 인라인입니다. 콘텐츠가 렌더링되고 콘텐츠의 시작 위치가 선택된 애니메이션의 from 키프레임이 됨으로써 애니메이션이 올바르게 시작됩니다. 이 접근 방식으로 인한 부작용 중 만족스러운 측면은 애니메이션이 복잡한 콘텐츠로 발생할 수 있는 진보적인 랜더링과 재레이아웃 또는 리소스 로딩을 감춘다는 것입니다.

콘텐츠를 숨기도록 전환하는 애니메이션을 설정하는 것도 매우 흥미롭습니다. onclick 처리기를 콘텐츠에서 주목되는 모든 요소(예: 모든 <a> 태그)에 연결하고 관련 애니메이션 속성(animation-name, animation-duration 등)을 설정할 수 있을 것이라는 가정을 할 수도 있습니다. 그러나, 실제로 탐색을 지연시키지 않는다면 유연한 전환은 기대할 수 없습니다.

이는 CSS 애니메이션 사양에 기술되어 있는 애니메이션 이벤트를 활용할 좋은 기회이기도 합니다. 특히, 언제 애니메이션이 끝나고(예를 들면 window.location.href를 설정하여) 탐색을 트리거하는지 감지하는 animationend 이벤트를 사용할 수도 있습니다. 따라서 onclick은 "보기에서 제거" 애니메이션을 트리거하고 처리기를 <body>animationend에 등록하여 탐색 이벤트가 발생하도록 합니다.

라이브 데모 제공

여기서 제시한 내용에서 더 나아가 보다 깊이 있는 예시를 보여주기 위해 CSS 변환 및 애니메이션 불러오기 페이지에 대한 데모 및 영어 자습서를 만들었습니다. 이 자습서는 Windows 8의 Internet Explorer 10과 최신 버전의 Chrome 및 Firefox에서 페이지를 탐색하는 동안에 전체 페이지 애니메이션을 자체 활용합니다.

페이지마다 애니메이션을 즐기기 위해서는 각 페이지의 우측 하단 코너에 있는 "~로 계속" 링크를 사용하여 자습서 페이지를 거치는 것이 좋습니다.

이 자습서의 마지막 부분에는 자신의 웹 콘텐츠와 애니메이션을 통합하는 방법에 대한 몇 가지 추가적인 지침과 샘플 코드가 나와 있습니다.

결론

CSS 변환과 CSS 애니메이션은 강력한 기능이며, 웹에 더욱 몰입할 수 있는 경험을 가능하게 합니다. 이 블로그 글에서는 웹 콘텐츠를 구현하기 위한 CSS 변환과 CSS 애니메이션의 사용에 대해 간단히 소개했습니다. 이제 여러분은 보다 유연하고 앱 수준의 탐색 경험을 제공하는 웹 페이지(정적인 웹도 포함)를 쉽게 만들 수 있습니다.

- Internet Explorer 그래픽 부문 프로그램 관리자 인턴, Charilaos “Harris” Papadopoulos