화면이동(transition) 기능으로 2D 전환(transform)에 생동감 부여하기
앞선 포스팅에서 언급했듯이 CSS transform은 애니메이션과 결합할 때 그 진정한 힘과 다양한 위력을 발휘할 수 있게 됩니다.
자바스크립트의 도움없이 순수하게 CSS, 엄밀히 말하자면 "CSS3 transition(전이)"만을 사용하여 다양한 효과를 나타낼 수 있습니다.
CSS transition(전이,화면이동) 소개
transform과 마찬가지로 전이는 CSS에 추가된 강력한 기능으로 애니메이션 형식으로 그 능력을 한 차원 끌어올렸습니다.
CSS 전이를 CSS 애니메이션 모듈과 혼동하면 안됩니다. 후자는 완전히 별개입니다.
애니메이션 모듈은 훨씬 더 규모가 크고 복잡하며 다양한 능력을 가지고 있습니다.
그렇다면 CSS 전이는 무엇이고 CSS 애니메이션과 어떻게 다를까?
간단히 말해서 전이는 요소가 한 상태에서 다른 상태로 변화(hover 효과와 같은 종류)할 때 이 변화가 일정 시간 동안 애니메이션화하거나 transitioned, 즉 변천 과정을 겪는 것을 말합니다.
CSS 전이는 일정시간 동안에 변천 과정을 겪는 것을 말한다.
이 툴은 복잡한 자바스크립트의 코드들을 간단하고 가독성이 좋은 단 한줄의 CSS로 바꿀 수 있습니다.
다음의 코드는 많은 이들이 jQuery 라이브러리를 사용하여 0.5초동안 요소를 희미하게 만드는 방법을 보여주는 것입니다.
hover 될 때 불투명도가 원 상태보다 절반으로 떨어지고 hover 가 해제되면 원상태로 돌아가는 예제입니다.
$('a').hover(
function () {
$(this).stop().animate({opacity : '.5'}, 500);
},
function () {
$(this).stop().animate({opacity : '1'}, 500);
});
이 예제는 복잡하지는 않지만 아주 간단한 효과를 내는 것에 비해 조금 긴 것 같습니다.
적어도 코드 상에서 jQeury를 포함해야 한다는 구문, 즉 사용자가 자바스크립트가 가능한 브라우저를 필요로 한다는 부분은 언급하지 않았다는 것도 감안해야 할 것입니다.
위 예지는 CSS 전이를 사용하는 방식으로 바꾼다면 다음과 같을 것입니다.
a {
transition: .5s;
}
a:hover {
opacity: .5;
}
위 방법은 jQuery를 이용하는 것보다 시간과 노력이 훨씬 더 적게 들뿐 아니라 코드는 단순해져서 가독성도 높아졌습니다.
간단한 효과를 위해서는 간단한 코드를! 그것이 정석입니다.
물론 이 예제는 jQuery와 비교해서 간단명료하다는 점을 강조하기 위해 최소한의 문법만을 사용한 것입니다.
지금부터 이러한 속성들에 대해 알아보고자 합니다.
전이(transition) 제어
transition-property
전이를 제어하는 속성들 중에는 transition-property
라는 속성이 있습니다.
이 속성은 전이 효과를 적용하기 원하는 속성들을 명시할 수 있습니다.
예를 들어 background-color가 본래 노란색인데 :hover 상태에서는 푸른색으로 "서서히" 변화하는 효과를 그리고 텍스트 컬러는 "즉시" 검정에서 흰색으로 변하기를 원한다고 가정해 봅니다
다시 말해서, background-color 에서는 전이(transition) 변화가 일어나길 원하지만, 텍스트 컬러는 전이변화를 바라지 않는 상황입니다.
a {
background: yellow;
color: #000;
/* 전이가 일어날 속성값을 정의 */
transition-property: background-color;
}
a:hover {
background-color: blue;
color: #fff;
}
위 예제는 오로지 background-color 만이 :hover 상태에서 애니메이션과 같은 효과를 나타내게 합니다.
또 이 속성에 all 값을 명시할 수도 있습니다. 그러면 당연히 모든 속성 변화에 전이 효과를 적용하게 됩니다.
all은 기본값이기 때문에 모든 속성변화에 적용되기를 바란다면 생략이 가능합니다.
transition-duration
그런데 위 예제는 현 상태에서는 동작하지 않을 것입니다. 단 한 가지가 빠져 있기 때문입니다.
바로 전이 제어, 즉 transition-duration
속성이 없기 때문입니다.
이 속성은 전이가 발생되는 시간을 명시하는 속성으로 밀리초(millisecond, ms) 또는 초(second, s)를 설정할 수 있습니다.
a {
background: yellow;
color: #000;
/* 전이가 일어날 속성값을 정의 */
transition-property: background-color;
/* 전이가 발생되는 시간 명시 */
transition-duration: 1s; /* 1000밀리초와 같다 */
}
a:hover {
background-color: blue;
color: #fff;
}
위 코드는 노란색에서 푸른색으로 background-color에 전이 변화가 일어나되 1초간 지속되도록 하라는 의미입니다.
transition-timing-function
이제부터 조금 복잡한 상황이 전개됩니다.
transition-timing-function
속성이 등장하기 때문입니다.
이 속성은 간단히 말해서 전이가 명시된 시간 동안 어떤 식으로 가속을 하고 감속을 하는지를 나타내는 속성입니다.
a {
background: yellow;
color: #000;
transition-property: background-color;
transition-duration: 1s; /* 1000밀리초와 같다 */
transition-timing-function: linear;
}
a:hover {
background-color: blue;
color: #fff;
}
transition-timing-function 속성은 사전에 정의한 키워드 리스트의 값을 허용한다.
이들만으로도 대부분의 상황에서는 충분할 것이다.
그러나 나중에 다루게 될 cubic-bezier() 함수를 사용하여 사용자가 직접 지정할 수도 있다.
이 타이밍 함수(linear)는 애니메이션이 지속되는 기간 내내 전이가 일정한 속도를 유지하면서 발생하도록 합니다.
기본값인 ease의 경우는 전이 효과를 최대 스피드로 빠르게 하다가 그 후 약간 점진적으로 속도를 낮추게 됩니다.
그 외의 사용자 정의 키워드들은 cubic-bezier() 함수의 단축 형태와 같은 종류인데 나중에 다루도록 하겠습니다.
transition-delay
마지막으로 transition-delay
속성에 대해 알아봅니다.
이 속성은 전이 효과가 발생하는 시점으로부터 실질적으로 애니메이션이 시작되기까지 일정 시간을 선언하여 지연시킬 수 있게 해주는 속성입니다.
예를 들어 0.5s의 값이 주어진다면 요소가 hover 상태가 될 때 애니메이션이 곧바로 시작되지 않고 0.5초가 지난 다음에 시작하게 됩니다.
a {
transition-property: background-color;
transition-duration: 1s; /* 1000밀리초와 같다 */
transition-timing-function: linear;
transition-delay: .5s; /* 500밀리초 */
}
이것만으로도 간단 명료합니다.
하지만 이미 짐작했겠지만 transition
속성을 사용하여 속성들을 단축 문법으로 결합하면 훨씬 더 간단하게 사용할 수 있습니다.
Short Syntax(단축 문법)
앞에서 언급했듯이 필수적인 transition 값은 지속시간(duration) 매개변수입니다.
transition의 초기 값이 0초이면 너무 즉각적으로 변화를 일으켜서 전이를 볼 수 없기 때문입니다.
그리고 두 개의 시간 관련 속성인 transition-duration
과 transition-delay
의 순서에 대해서는 반드시 지켜야할 한가지 규칙이 있습니다.
항상 지속시간을 먼저 명시해야 한다는 것입니다.
이 한가지 외에는 원하는 대로 다양한 값들을 설정(지정)할 수 있습니다.
다음 예제는 모두 유효하고 동일한 결과를 도출합니다.
div {
transition: opacity .5s linear 2s;
transition: linear .5s opacity 2s;
transition: linear opacity .5s 2s;
transition: .5s 2s opacity linear;
}
전이 속성에 대한 이해
다음 예제를 살펴보면 transition 속성을 :hover 규칙에 추가하지 않고 요소의 기본 스타일에 추가하고 있다는 것을 알 수 있습니다.
틀린 예
a {
background: blue;
}
a:hover {
background: red;
transition: background .5s ease-in-out;
}
올바른 예
a {
background: blue;
transition: background .5s ease-in-out;
}
a:hover {
background: red;
}
틀린 예제가 흔히 범할 수 있는 오류입니다.
즉, 만약 해당 요소가 :hover 상태가 될 때 전이가 일어나기를 원할 경우 transition 속성은 반드시 :hover 규칙들 사이에 놓여지도록 해야 합니다.
이런 방식으로 배치를 하게 되면 요소가 :hover 상태가 될 때, 즉 일반적인 상태에서 :hover 상태로의 변화가 일어날 때 동작하게 됩니다.
그러나 :hover가 해제될 때는 요소가 다시 점진적으로 변하지 않고 본래의 기본 스타일로 매우 빠르게 되돌아가게 됩니다.
때때로 이런 효과를 일부러 원하는 경우도 있을 수 있겠지만 일반적으로 :hover 상태에서 전이가 서서히 이루어졌다가 다시 되돌아가기를 바랄 것입니다.
그래서 이런 식의 오류를 범하지 않도록 사고 방식을 다르게 가질 필요가 있습니다.
왜 이런 실수를 하는지 어느 정도 이해는 하지만 이렇게 오류를 범할 때 속성의 기능이 상당히 제한될 수 있습니다.
단순히 :hover에 애니메이션이 동작하도록 시도하기 보다는 모든 변화에 애니메이션이 일어나도록 transition 속성을 활용해야 할 것입니다.
예를 들어서 transition 속성이 기본 스타일(기본요소)에 적용된다면 요소에 일어나느 모든 변화, 즉 간단한 :hover 상태부터 :focus 상태, 심지어는 브라우저의 zoom(줌) 제어를 사용하는 동안에도 전이가 일어날 것입니다.
이런 결과들을 염두에 두고 활용한다면 전이를 잘못 사용하는 일이 없을 것이고 필요한 곳에서 보다 정확하게 적용할 수 있을 것입니다.
On & Off 전이 개별적으로 적용하기
앞에서도 언급했듯이 마우스 포인터가 요소에 접근할 때와 요소에서 멀어질 때 각각 다른 전이 효과를 원하는 경우도 생길 수 있습니다.
바로 이런 경우는 좀 전에 언급한 방식이 잘못 사용되는 것이 아니라 오히려 유효하게 활용되는 경우일 것입니다.
아래의 효과를 확인해 보도록 합니다.
See the Pen transition on & off test by jaeheekim (@jaehee) on CodePen.
위 코드는 해당 요소가 hover 될 때 사용되는 초기 전이에 관한 부분은 :hover 규칙이 있는 쪽으로 옮겨 졌고, 그곳에 본래의 상태로 변경될 때 애니메이션이 되도록 하는 다른 transition
속성이 그 자리를 차지하고 있습니다.
결과를 보면 요소가 hover 상태가 될 때 배경색이 푸른색에서 붉은색으로 1초에 걸쳐 변화하고 hover가 해제될 때 붉은색 배경이 푸른색으로 5초라는 더 긴 시가에 걸쳐 점진적으로 변하게 됩니다.
위보다 조금 복잡한 상황을 만들 수도 있습니다. 다음 코드와 효과를 살펴봅니다.
See the Pen transition on & off test #2 by jaeheekim (@jaehee) on CodePen.
위 예제는 앞선 코드와 많이 달라진 것은 없지만 근본적으로 매우 다른 효과를 보여주고 있습니다.
:hover 상태 전이는 transition-property
매개변수 사용으로 background
속성만 애니메이션으로 만들고 있습니다.
즉, 배경색이 푸른색에서 붉은색으로 1초 동안 전이가 진행되고 rotate() 함수에는 어떤 애니메이션도 적용되지 않았기 때문에 360deg의 값이 처음 :hover의 작용에 어떤 영향도 미치지 못합니다.(물론 360deg 값은 초기 0deg 값과 동일하다)
반대로 기본 규칙상의 transition 속성, 즉 hover 상태에서 본래의 상태로 돌아가는 변화에 주는 속성은 duration
매개변수만을 가지고 있습니다.
이때 마우스 포인터가 요소를 벗어나면 모든 속성들이 본래의 값으로 전이 효과를 통해 되돌아가게 될 것입니다.
왜냐하면 해당 요소가 :hover 상태에서 회전을 했기 때문에 (비록 회전에 애니메이션이 적용되지 않아서 회전이 일어난 것을 인지하지 못했겠지만 말이다.) 마우스 포인터가 요소에서 벗어날 때 요소는 360deg로 완벽하게 한 바퀴 회전하면서 본래의 0deg 값(본래 요소로 되돌아 갈 때는 transition의 애니메이션이 적용되어 있음)으로 되돌아가게 됩니다.
최종 결과물을 다시 간략하게 분석하면 다음과 같습니다.
- 사용자가 마우스를 요소 위로 가져가면 배경색이 1초동안 푸른색에서 붉은색으로 변화게 된다.
- 마우스 포인터가 요소를 벗어나면 배경색이 붉은색에서 푸른색으로 변하면서 요소는 반시계 방향으로 0.5초만에 360도를 회전하게 된다.
Timing Function
앞에서 언급한 바와 같이 transition-timing-function
속성은 애니메이션이 일어나는 속도를 조절하는 여러 가지 방법에 대한 것입니다.
이것은 애니메이션이 전이가 일어나는 구첵적인 시간동안 어느 지점에서 속도를 높이고 또 어느 지점에서 속도를 늦출 것인지를 나타냅니다.
그리고 cubic-bezier()
함수는 전이의 가속 패턴을 만드는 역할을 합니다.
transition-timing-function 이 수용하는 다섯 가지 사전 정의된 키워드가 있는데 특정 cubic-bezier() 값으로 단축하여 사용될 수 있습니다.
- ease
- linear
- ease-in
- ease-out
- ease-in-out
베지어 곡선(Bezier curve)
cubic-bezier()
함수는 베지어 곡선(Bezier curve)을 구성하는 데 도움이 되는 네 개의 소수값(일반적으로 0에서 1까지의 범위)으로 구성됩니다.
이때 이 베지어 곡선은 전이가 어느 시점에 가속되고 또 감속되는지를 결정합니다.
다음 코드는 전형적인 cubic-bezier() 함수를 보여주고 있는데 이 예제는 ease-in-out
키워드와 동일합니다.
/* cubic-bezier(x, y, x, y);*/
div {
transition-timing-function: cubic-bezier(.42, 0, .58, 1);
}
cubic-bezier() 함수는 그 개념을 이해하기가 쉽지 않습니다.
하지만 결과 애니메이션이 어떻게 베지어 곡선(커브)와 일치하는지를 살펴본다면 훨씬 쉬워질 것입니다.
스테핑 함수(stepping function)
타이밍 함수는 베지어 곡선뿐만 아니라 스테핑 함수(stepping function)로도 표현될 수 있습니다.
steps()
함수는 전이가 부드럽게 이루어지는 것이 아니라 여러 개의 단계를 명시하여 애니메이션을 단계별로 분리시킵니다.
이 함수는 두 개의 매개변수를 수용합니다.
첫 번째는 몇 단계인지를 나타내는 양수인 정수입니다.(소수는 수용되지 않음)
두 번째는 start 또는 end의 값으로 상태의 변화가 단계의 시작 또는 끝에서 발생해야 한다는 것을 나타내는 것입니다.(end 값이 기본값으로 선택사항이다)
예를 들어서 만약 각 단계의 간격이 3초라면 start의 값은 3초가 시작되는 지점에서 상태 변화를 유도하게 될 것입니다.
반면 end 값은 3초가 지난 후에 상태 변화를 유도할 것입니다.
다음 예제를 살펴봅니다.
div {
width: 200px;
height: 200px;
transition: 5s steps(5, start);
}
div:hover {
transform: translate(500px, 0)
}
이 코드는 hover 상태가 될 때 div가 5초 동안 5단계로 500px만큼 이동한다는 것을 나타내는 것입니다.
steps(5, start) 함수 때문에 결과적으로 박스가 매 초당 100px만큼 이동하게 됩니다. 그래서 박스가 hover 상태가 되면 즉시 100px 지점까지 즉시 이동하게 됩니다.(첫 번째 움직임은 start 매개변수 덕분에 즉각적으로 이루어진다.)
실질적으로 사용할 때는 애니메이션의 프레임들을 포함하는 스프라이트 이미지로 생각하면 될 것입니다.
만약 이미지를 요소의 배경으로 적용한다면, 그때는 background-position 을 사용하여 스프라이트 이미지를 왼쪽으로 끝까지 움지이게 하고 이런 위치의 변화를 전이를 사용하여 애니메이션화할 수 있을 것입니다.
다음의 동작을 확인해 봅니다.
See the Pen transition 스텝핑 함수 by jaeheekim (@jaehee) on CodePen.
마치며
지금까지 전이에 대한 이론에 대해 알아보았습니다.
위에 언급한 내용으로 충분하지 않을 수는 있지만 전반적 이해에는 도움이 되길 바랍니다.
다음에는 좀 더 흥미진진한 부분으로 이 전이 활용에 대해 다뤄보도록 하겠습니다.
related links
'StyleSheet > CSS' 카테고리의 다른 글
CSS3 @namespace (0) | 2016.09.29 |
---|---|
CSS3 transform(화면 변형) (0) | 2016.09.29 |
transition(전이,화면 이동) (0) | 2016.09.29 |
CSS3 transform - 2D 전환 (0) | 2016.09.29 |
애니메이션을 위한 X, Y, Z 축의 이해 (0) | 2016.09.29 |