본문으로 바로가기

CSS3 transition(화면이동,전이)

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

화면이동(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 가 해제되면 원상태로 돌아가는 예제입니다.

javascript
$('a').hover(
    function () {
        $(this).stop().animate({opacity : '.5'}, 500);
    },
    function () {
        $(this).stop().animate({opacity : '1'}, 500);
});

이 예제는 복잡하지는 않지만 아주 간단한 효과를 내는 것에 비해 조금 긴 것 같습니다. 

적어도 코드 상에서 jQeury를  포함해야 한다는 구문, 즉 사용자가 자바스크립트가 가능한 브라우저를 필요로 한다는 부분은 언급하지 않았다는 것도 감안해야 할 것입니다.


위 예지는 CSS 전이를 사용하는 방식으로 바꾼다면 다음과 같을 것입니다.

css
a {
    transition: .5s;
}

a:hover {
    opacity: .5;
}

위 방법은 jQuery를 이용하는 것보다 시간과 노력이 훨씬 더 적게 들뿐 아니라 코드는 단순해져서 가독성도 높아졌습니다.

간단한 효과를 위해서는 간단한 코드를! 그것이 정석입니다.

물론 이 예제는 jQuery와 비교해서 간단명료하다는 점을 강조하기 위해 최소한의 문법만을 사용한 것입니다.


지금부터 이러한 속성들에 대해 알아보고자 합니다.




전이(transition) 제어


transition-property

전이를 제어하는 속성들 중에는 transition-property 라는 속성이 있습니다.

이 속성은 전이 효과를 적용하기 원하는 속성들을 명시할 수 있습니다.

예를 들어 background-color가 본래 노란색인데 :hover 상태에서는 푸른색으로 "서서히" 변화하는 효과를 그리고 텍스트 컬러는 "즉시" 검정에서 흰색으로 변하기를 원한다고 가정해 봅니다

다시 말해서, background-color 에서는 전이(transition) 변화가 일어나길 원하지만, 텍스트 컬러는 전이변화를 바라지 않는 상황입니다.

css
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)를 설정할 수 있습니다.

css
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 속성이 등장하기 때문입니다.

이 속성은 간단히 말해서 전이가 명시된 시간 동안 어떤 식으로 가속을 하고 감속을 하는지를 나타내는 속성입니다.

css
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초가 지난 다음에 시작하게 됩니다.

css
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-durationtransition-delay의 순서에 대해서는 반드시 지켜야할 한가지 규칙이 있습니다.

항상 지속시간을 먼저 명시해야 한다는 것입니다. 

이 한가지 외에는 원하는 대로 다양한 값들을 설정(지정)할 수 있습니다.


다음 예제는 모두 유효하고 동일한 결과를 도출합니다.

css
div {
   transition: opacity .5s linear 2s;
   transition: linear .5s opacity 2s;
   transition: linear opacity .5s 2s;
   transition: .5s 2s opacity linear;
}



전이 속성에 대한 이해

다음 예제를 살펴보면 transition 속성을 :hover 규칙에 추가하지 않고 요소의 기본 스타일에 추가하고 있다는 것을 알 수 있습니다.

틀린 예

css
a {
    background: blue;
}
a:hover {
    background: red;
    transition: background .5s ease-in-out;
}


올바른 예

css
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 키워드와 동일합니다.

css
/* 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초가 지난 후에 상태 변화를 유도할 것입니다.


다음 예제를 살펴봅니다.

css
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.



마치며

지금까지 전이에 대한 이론에 대해 알아보았습니다. 

위에 언급한 내용으로 충분하지 않을 수는 있지만 전반적 이해에는 도움이 되길 바랍니다.

다음에는 좀 더 흥미진진한 부분으로 이 전이 활용에 대해 다뤄보도록 하겠습니다.





Jaehee's WebClub


'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