- animation-name
- animation-duration
- animation-interation-count
- animation-delay
- animation-direction
- animation:
3s infinite alternate slidein
0. File download1. Keyframe1.1 Keyframe에 대하여1.2. Keyframe 규칙1.3 Animation 적용하기1.3.1 animation의 단일 속성들2. 실행해 보며 배우는 Keyframe 예제2.1 빌딩 올리기2.2 빌딩 2개 올리기2.3 빌딩 3개와 냥이집사님 배치2.4 빌딩 3개와 냥이집사님 걷게하기2.5 여러분을 위한 과제
0. File download
링크로 다운로드가 안되시는 분은 아래 파일을 받아주세요.
1. Keyframe
1.1 Keyframe에 대하여
@keyframes
에 대하여 가벼운 예제를 보고 가도록 하겠습니다.<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>animation</title> <style> /* 키프레임 이름 == 애니메이션 이름 */ @keyframes hojun { 0% { background-color: rosybrown; color: white; transform: translate(0, 0); } 100% { color: red; background-color: royalblue; transform: translate(300px, 0) rotate(360deg) scale(2); } } div { margin: 200px; width: 100px; height: 100px; background-color: red; animation: hojun 10s; } </style> </head> <body> <div>hello world</div> </body> </html>
해당
@keyframes
hojun을 설정하여 div의 animation으로 1초간격으로 주면 아래와 같이 실행되게 됩니다.
이처럼 Keyframe은 어떤 변화가 일어나는 지점을 설정하여 특정 시간 동안 해당 Property와 Value를 변화시킵니다.
+ transition과 animation의 차이점
transition과 animation 속성은 Javascript의 도움 없이 오브젝트에 직접 애니메이션 효과를 적용할 때 사용합니다. transition과 animation은
요소 상태에 대한 의존 여부
에 대해 차이를 가집니다. transition은 요소의 상태가 변경되어야 애니메이션을 실행할 수 있지만, animation 속성은 요소의 상태 변화와 관계없이 애니메이션을 실행할 수 있습니다. 또한 animation 속성은 @keyframes
속성을 이용해 프레임을 추가할 수 있습니다.1.2. Keyframe 규칙
@keyframes
은 애니메이션이 만들어지는 부분입니다. from
속성이나 0%
속성에 설정한 스타일부터 to
속성이나 100%
속성에 설정한 스타일로 점차 변경되면서 애니메이션이 재생됩니다. 0%과 100% 사이에는 여러 개의 중간 속성을 설정할 수 있습니다./* [ from ~ to 속성 ] */ @keyframes animation-name { /* 애니메이션의 시작 프레임 */ from { styles; } /* 애니메이션의 종료 프레임 */ to { styles; } /* [ 0% ~ 100% 속성 ] */ @keyframes animation-name { /* 애니메이션의 시작 프레임 */ 0% { styles; } 50% { styles; } /* 애니메이션의 종료 프레임 */ 100% { styles; }
1.3 Animation 적용하기
CSS3 애니메이션을 이용하면 여러 개의 CSS 스타일을 부드럽게 전환시킬 수 있습니다.
@keyframes
은 CSS 스타일의 변화 과정을 나타낼 때 사용됩니다. @keyframes
을 이용한 애니메이션은 @transition
보다 정밀한 효과를 구현할 수 있습니다.1.3.1 animation의 단일 속성들
- animation-name
애니메이션을 재생(호출) 하기 위해서는 반드시 이름을 정의해야 합니다. name은
@keyframes
속성에서 설정한 이름을 동일하게 사용합니다.
/* 키프레임 이름 == 애니메이션 이름 */ @keyframes yoon { 0% { styles; } 100% { styles; } } div{ /* 애니메이션 이름 */ animation-name: yoon; }
+ animation-name 이름 규칙
animation-name의 시작에는
영문 소문자, 숫자, 문자열, 언더바(_), 하이픈(-)
을 사용합니다. 영문 대문자, 숫자, 특수문자는 사용할 수 없습니다(파일 및 폴더명에는 허용). 여러 개의 animation-name을 동시에 나열할 경우 ,
를 사용합니다./* [ 올바른 이름 예시 ] */ animation-name: yoon; /* 영문 소문자로 시작하는 이름 */ animtaion-name: _yoon; /* 언더바(_)로 시작하는 이름 */ animation-name: -yoon; /* 하이픈(-)으로 시작하는 이름 */ animation-name: yoon1, yoon2; /* 여러 개의 animation-name 나열 */ /* [ 잘못된 이름 예시 ] */ animation-name: Name-yoon; /* 영문 대문자로 시작하는 이름 */ animation-name: *-name-yoon; /* 특수문자로 시작하는 이름 */ animation-name: 1yoon; /* 숫자로 시작하는 이름 */
- animation-duration
duration 속성은 애니메이션의 시작부터 종료까지의 총 지속 시간을 설정할 때 사용하며, transition-duration과 유사한 기능을 제공합니다. duration 값은
양수
로 지정해야 그 결과를 확인할 수 있습니다. 속성 값을 0 혹은 음수로 설정했을 경우 애니메이션이 실행되지 않습니다.
/* [ 애니메이션이 재생되지 않는 경우 ] */ animation-duration: 0; /* 재생시간이 0인 경우 */ animation-duration: -3s; /* 재생시간이 음수인 경우 */ /* [ 애니메이션이 재생되는 경우 ] */ animation-duration: 3s; /* 재생시간이 양수인 경우 */ animation-duration: 500ms; /* 1초 이하의 재생시간을 입력할 경우 */
duration 속성의 결과는 아래의 전체 코드를 통해 확인할 수 있습니다.
<!DOCTYPE html> <html> <head> <style> @keyframes yoon { from {transform: translate(100px, 0);} to {transform: translate(300px, 0);} } div { position: absolute; margin: 50px; width: 100px; height: 100px; background-color: #ff0000; /* 애니메이션 이름 */ animation-name: yoon; } /* [ 재생시간이 0인 경우 ] */ .duration_0s { top: 20px; animation-duration: 0; } /* [ 재생시간이 음수인 경우 ] */ .duration_minus { top: 130px; animation-duration: -3s; } /* [ 재생시간이 양수인 경우 ] */ .duration_plus { top: 240px; animation-duration: 3s; } /* [ 1초 이하의 재생시간을 입력할 경우 ] */ .duration_ms { top: 350px; animation-duration: 500ms; } </style> </head> <body> <div class="duration_0s">0s</div> <div class="duration_minus">minus</div> <div class="duration_plus">plus</div> <div class="duration_ms">ms</div> </body> </html>
- animation-iteration-count
위의 duration 코드 예제를 실행시키면 애니메이션이 1회 재생 후 종료되는 것을 알 수 있습니다. iteration-count 속성은 애니메이션을 재생하는 횟수를 지정할 때 사용합니다. iteration-count 속성의 기본 값은
1
이며, 0으로 값을 지정할 경우 애니메이션이 재생되지 않습니다. 음수로 속성 값을 지정할 경우 기본 값인 1과 같은 결과를 출력하고, 자연수가 아닌 양의 유리수(ex. 1.5)로 속성 값을 지정할 경우 애니메이션 재생 도중 첫 번째 프레임으로 돌아가 종료됩니다.infinite
로 값을 설정할 경우 애니메이션을 무한 반복할 수 있습니다.
/* [ 애니메이션이 재생되지 않는 경우 ] */ animation-iteration-count: 0; /* 재생횟수가 0인 경우 */ animation-iteration-count: -3; /* 재생횟수가 음수인 경우 */ /* [ 애니메이션이 재생되는 경우 ] */ animation-iteration-count: 3; /* 재생횟수가 양수인 경우 */ animation-iteration-count: 1.5; /* 재생횟수가 실수인 경우 */ animation-iteration-count: infinite; /* 애니메이션을 무한 반복할 경우 */
iteration-count 속성의 결과는 아래의 전체 코드를 통해 확인할 수 있습니다.
<!DOCTYPE html> <html> <head> <style> @keyframes yoon { from {transform: translate(100px, 0);} to {transform: translate(300px, 0);}} } div { position: absolute; margin: 50px; width: 100px; height: 100px; background-color: #ff0000; /* 애니메이션 속성 */ animation-name: yoon; animation-duration: 1s; } /* [ 재생횟수가 0인 경우 ] */ .iteration-count_0 { top: 20px; animation-iteration-count: 0; } /* [ 재생횟수가 음수인 경우 ] */ .iteration-count_minus { top: 130px; animation-iteration-count: -3; } /* [ 재생횟수가 양수인 경우 ] */ .iteration-count_plus { top: 240px; animation-iteration-count: 3; } /* [ 재생횟수가 유리수인 경우 ] */ .iteration-count_rational { top: 350px; animation-iteration-count: 1.5; } /* [ 애니메이션을 무한 반복할 경우 ] */ .iteration-count_infinite { top: 460px; animation-iteration-count: infinite; } </style> </head> <body> <div class="iteration-count_0">0</div> <div class="iteration-count_minus">minus</div> <div class="iteration-count_plus">plus</div> <div class="iteration-count_rational">rational</div> <div class="iteration-count_infinite">infinite</div> </body> </html>
- animation-direction
애니메이션의 재생 방향을 설정할 때 direction 속성을 사용합니다. direction 속성의 기본 값은
from
또는0%
에 설정된 스타일에서to
또는100%
에 설정된 스타일대로 재생하는normal
입니다. direction 속성의 종류는 다음과 같습니다.
animation-direction: normal; /* 순방향 재생 */ animation-direction: reverse; /* 역방향 재생 */ animation-direction: alternate; /* 순방향 시작, 순방향-역방향 번갈아 재생 */ animation-direction: alternate-reverse; /* 역방향 시작, 역방향-순방향 번갈아 재생 */
alternate와 alternate-reverse는 서로 반대의 결과를 보여줍니다.
alternate
은 순방향으로 애니메이션을 시작해 실행 횟수가 홀수일 때에는 순방향으로, 짝수일 때에는 역방향으로 재생합니다. 반면, alternate-reverse
은 역방향으로 애니메이션을 시작해 실행 횟수가 홀수일 때에는 역방향으로, 짝수 일 때에는 순방향으로 재생합니다.
direction 속성의 결과는 아래의 전체 코드에서 확인할 수 있습니다.<!DOCTYPE html> <html> <head> <style> @keyframes yoon { from {transform: translate(100px, 0);} to {transform: translate(300px, 0);}} div { position: absolute; margin: 50px; width: 100px; height: 100px; background-color: #ff0000; /* 애니메이션 속성 */ animation-name: yoon; animation-duration: 1s; animation-iteration-count: infinite;} /* [ 순방향 재생 ] */ .direction_normal { top: 20px; animation-direction: normal;} /* [ 역방향 재생 ] */ .direction_reverse { top: 130px; animation-direction: reverse} /* [ 순방향 시작, 순방향-역방향 번갈아 재생 ] */ .direction_alternate { top: 240px; animation-direction: alternate;} /* [ 역방향 시작, 역방향-순방향 번갈아 재생 ] */ .direction_alternate-reverse { top: 350px; animation-direction: alternate-reverse;} </style> </head> <body> <div class="direction_normal">normal</div> <div class="direction_reverse">reverse</div> <div class="direction_alternate">alternate</div> <div class="direction_alternate-reverse">alternate-reverse</div> </body> </html>
- animation-timing-function
timing-function은 애니메이션
@keyframes
사이의 재생 속도를 조절하는 속성으로, transion-timing-function 속성과 유사한 결과를 제공합니다. timing-function 속성의 종류로는ease, linear, ease-in, ease-out, ease-in-out, cubic-bezier(n, n, n, n)
등이 있습니다.
[ 같은 애니메이션 결과를 출력하는 속성값 ] animation-timing-function: ease; /* 기본값 */ animation-timing-function: cubic-bazier(0,25, 0.1, 0.25, 1); animation-timing-function: linear; animation-timing-function: cubic-bazier(0,0,1,1); animation-timing-function: ease-in; animation-timing-function: cubic-bazier(0.42,0,1,1); animation-timing-function: ease-out; animation-timing-function: cubic-bazier(0,0,0.58,1); animation-timing-function: ease-in-out; animation-timing-function: cubic-bazier(0.42,0,0.58,1);
각 속성값에 대한 속도 그래프는 다음과 같으며, cubic-bezier의 n 값에 따른 변화는 https://cubic-bezier.com/ 에서 확인할 수 있습니다.

- animation-delay
애니메이션 시작을 지연시키고 싶을 경우, delay 속성을 사용합니다. delay 속성의 기본 값은 애니메이션이 지연 없이 시작되는
0
또는now
입니다. 값이음수
일 경우 지정된 시간이 지난 뒤의 장면부터 지연 없이 애니메이션이 시작됩니다.
animation-delay: 0; /* 바로 재생 */ animation-delay: now; /* 바로 재생 */ animation-delay: 1.5s; /* 지연 재생 */ animation-delay: -500ms; /* 지정 시간 이후 프레임부터 바로 재생 */
delay 속성의 결과는 아래의 전체 코드에서 확인할 수 있습니다.
<!DOCTYPE html> <html> <head> <style> @keyframes yoon { from {transform: translate(100px, 0)} to {transform: translate(300px, 0);}} div { position: absolute; margin: 50px; width: 100px; height: 100px; background-color: #ff0000; /* 애니메이션 속성 */ animation-name: yoon; animation-duration: 1s; animation-iteration-count: 1;} /* [ 바로 재생 ] */ .delay_0 { top: 20px; animation-delay: 0;} /* [ 바로 재생 ] */ .delay_now { top: 130px; animation-delay: now;} /* [ 지연 재생 ] */ .delay_plus { top: 240px; animation-delay: 1.5s;} /* [ 지정 시간 이후 프레임부터 바로 재생 ] */ .delay_minus { top: 350px; animation-delay: -500ms;} </style> </head> <body> <div class="delay_0">0</div> <div class="delay_now">now</div> <div class="delay_plus">plus</div> <div class="delay_minus">minus</div> </body> </html>
- animation-play-state
재생여부를 설정할 경우 play-state 속성을 사용합니다. 속성값이
running
일 경우 애니메이션을 재생하고,paused
일 경우 애니메이션을 정지합니다.
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://code.jquery.com/jquery-3.2.0.min.js"></script> <script type="text/javascript"> $(function () { $('.play').click(function () { $('div').css('animation-play-state', 'running'); }); $('.stop').click(function () { $('div').css('animation-play-state', 'paused'); }); }); </script> <style> @keyframes yoon { from { transform: translate(100px, 0); } to { transform: translate(300px, 0); } } div { position: absolute; margin: 50px; width: 100px; height: 100px; background-color: #ff0000; /* 애니메이션 속성 */ animation-name: yoon; animation-duration: 2s; animation-iteration-count: infinite; } </style> </head> <body> <button class="play">running</button> <button class="stop">paused</button> <div>box</div> </body> </html>
2. 실행해 보며 배우는 Keyframe 예제
2.1 빌딩 올리기
아래 예제(
002.html
)는 keyframes를 이용하여 background 이미지를 animation steps를 이용하여 순차적으로 옆으로 넘기며 마치 빌딩이 지어지는 것처럼 보이게 하는 예제입니다.<!DOCTYPE html> <html> <head> <style> @keyframes hojun { from{ background-position: 0px, 0px; } to { background-position: -3730px, 0; } } .building1 { width: 110px; height: 180px; background: url(./animation/building/building1.png) no-repeat; animation: hojun 5s steps(33); animation-fill-mode: forwards; } </style> </head> <body> <div class="building1"></div> </body> </html>
이 예제를 실행시키면 아래와 같은 이미지가 순차적으로 5초의 시간 간격을 가지고 세워지는 것처럼 보이는 것을 알 수 있습니다.

이 코드에서
from
과 to
는 0%와 100%입니다. 여기서 background-position: -3730px, 0
값이 to
에 있는 이유는 이미지가 왼쪽 상단에 0, 0에서 옆으로 하나의 장면이 넘어가며 이미지의 Position은 결국 마이너스의 값을 가지게 되기 때문입니다.또,
animation: hojun 5s steps(33);
에 스탭이 있는 이유는 이미지가 부드럽게 옆으로 넘어가는 것이 아니라 각각의 장면이 끊어지면서 건물을 보여줘야 하기 때문에 그렇습니다.2.2 빌딩 2개 올리기
아래 예제(
003.html
)는 위와 같은 방식으로 2개의 건물을 올리는 코드입니다. 여기서 background-position에 마이너스 값은 이미지의 길이입니다. 스탭은 총 넓이를 각각의 이미지에 건물 이미지 넓이를 나눈 값입니다.<!DOCTYPE html> <html> <head> <style> @keyframes one { from{ background-position: 0px, 0px; } to { background-position: -3730px, 0; } } @keyframes two { from{ background-position: 0px, 0px; } to { background-position: -5346px, 0; } } .building1{ width: 110px; height: 180px; background: url(./animation/building/building1.png) no-repeat; animation: one 5s steps(33); animation-fill-mode: forwards; } .building2{ width: 165px; height: 180px; background: url(./animation/building/building2.png) no-repeat; animation: two 5s steps(32); animation-fill-mode: forwards; transform: translate(300px, 300px); } </style> </head> <body> <div class="building1"></div> <div class="building2"></div> </body> </html>
2.3 빌딩 3개와 냥이집사님 배치
이번에는 주인공인 냥이 집사님을 배치해보도록 하겠습니다. 좀 더 자유로운 포지셔닝을 위해 html코드는 아래와 같이 배치하였습니다.
<div class="back"> <div class="cat"></div> <div class="building1"></div> <div class="building2"></div> <div class="building7"></div> </div>
여기서
back
class에는 relative
속성을 주고 그 아래 있는 div
는 absolute
속성을 부여하여 자유로운 배치가 가능하도록 하였습니다. @keyframes cat { 33.3% { transform: translateY(0) scale(0.3); background: url(./animation/cat/1.png) no-repeat; } 66.6% { transform: translateX(-100px) scale(0.3); background: url(./animation/cat/2.png) no-repeat; } 100% { transform: translateX(-200px) scale(0.3); background: url(./animation/cat/3.png) no-repeat; } }
animation 부분만 한 번 보도록 하겠습니다.
background
에서 이미지 3개를 교체함으로 마치 냥이 집사님이 걷는 것처럼 구현하려 하였습니다. 여기에 냥이 집사님이 걸어야 하므로 Y
축으로 이동을 하게 하였고, 냥이 집사님의 몸집이 너무 커서 scale(0.3)
의 속성을 부여하였습니다.아래 코드는 모든 코드입니다.
<!DOCTYPE html> <html> <head> <style> body, img, div{ padding: 0; margin: 0; } @keyframes one { from{ background-position: 0px, 0px; } to { background-position: -3730px, 0; } } @keyframes two { from{ background-position: 0px, 0px; } to { background-position: -5346px, 0; } } @keyframes seven { from{ background-position: 0px, 0px; } to { background-position: -3300px, 0; } } @keyframes cat { 33.3% { transform: translateY(0) scale(0.3); background: url(./animation/cat/1.png) no-repeat; } 66.6% { transform: translateX(-100px) scale(0.3); background: url(./animation/cat/2.png) no-repeat; } 100% { transform: translateX(-200px) scale(0.3); background: url(./animation/cat/3.png) no-repeat; } } .building1{ width: 110px; height: 180px; background: url(./animation/building/building1.png) no-repeat; animation: one 5s steps(33); animation-fill-mode: forwards; transform: scale(0.5); position: absolute; top: 10px; left: 10px; } .building2{ width: 165px; height: 180px; background: url(./animation/building/building2.png) no-repeat; animation: two 5s steps(32); animation-fill-mode: forwards; transform: scale(0.5); position: absolute; top: 300px; left: 300px; } .building7{ width: 150px; height: 180px; background: url(./animation/building/building7.png) no-repeat; animation: seven 5s steps(22); animation-fill-mode: forwards; position: absolute; top: 170px; left: 150px; } .cat{ width: 313px; height: 436px; background: url(./animation/cat.png) no-repeat; animation: cat .5s infinite; transform: scale(0.3); position: absolute; top: 10px; left: 600px; } .back{ width: 100vw; height: 150vh; background-color: YellowGreen; position: relative; } </style> </head> <body> <div class="back"> <div class="cat"></div> <div class="building1"></div> <div class="building2"></div> <div class="building7"></div> </div> </body> </html>
2.4 빌딩 3개와 냥이집사님 걷게하기
다음 파일은(
006.html
) 위 파일에서 냥이 집사님이 좀 더 현실적으로 걷게 하는 코드입니다. %를 10%로 나누고 마지막에 냥이 집사님이 자연스럽게 걷다가 멈추게 하였습니다.좀 더 세부적으로 말씀을 드리자면 가속도가 붙지 않게 하기 위해
animation: cat 3s linear;
를 주었습니다. 또한 마지막에 냥이 집사님을 멈추게 하기 위해 animation-fill-mode: forwards;
속성을 부여하였습니다.%는 10%로 나눈 것에서
Y
축 값을 -20px
로 주었습니다.<!DOCTYPE html> <html> <head> <style> body, img, div{ padding: 0; margin: 0; } @keyframes one { from{ background-position: 0px, 0px; } to { background-position: -3730px, 0; } } @keyframes two { from{ background-position: 0px, 0px; } to { background-position: -5346px, 0; } } @keyframes seven { from{ background-position: 0px, 0px; } to { background-position: -3300px, 0; } } @keyframes cat { 10% { transform: translateY(0) scale(0.3); background: url(./animation/cat/1.png) no-repeat; } 20% { transform: translateX(-20px) scale(0.3); background: url(./animation/cat/2.png) no-repeat; } 30% { transform: translateX(-40px) scale(0.3); background: url(./animation/cat/3.png) no-repeat; } 40% { transform: translateX(-60px) scale(0.3); background: url(./animation/cat/1.png) no-repeat; } 50% { transform: translateX(-80px) scale(0.3); background: url(./animation/cat/2.png) no-repeat; } 60% { transform: translateX(-100px) scale(0.3); background: url(./animation/cat/3.png) no-repeat; } 70% { transform: translateX(-120px) scale(0.3); background: url(./animation/cat/1.png) no-repeat; } 80% { transform: translateX(-140px) scale(0.3); background: url(./animation/cat/2.png) no-repeat; } 90% { transform: translateX(-160px) scale(0.3); background: url(./animation/cat/3.png) no-repeat; } 100% { transform: translateX(-180px) scale(0.3); background: url(./animation/cat/1.png) no-repeat; } } .building1{ width: 110px; height: 180px; background: url(./animation/building/building1.png) no-repeat; animation: one 5s steps(33); animation-fill-mode: forwards; transform: scale(0.5); position: absolute; top: 10px; left: 10px; } .building2{ width: 165px; height: 180px; background: url(./animation/building/building2.png) no-repeat; animation: two 5s steps(32); animation-fill-mode: forwards; transform: scale(0.5); position: absolute; top: 300px; left: 300px; } .building7{ width: 150px; height: 180px; background: url(./animation/building/building7.png) no-repeat; animation: seven 5s steps(22); animation-fill-mode: forwards; position: absolute; top: 170px; left: 150px; } .cat{ width: 313px; height: 436px; background: url(./animation/cat.png) no-repeat; animation: cat 3s linear; animation-fill-mode: forwards; transform: scale(0.3); position: absolute; top: 10px; left: 600px; } .back{ width: 100vw; height: 150vh; background-color: YellowGreen; position: relative; } </style> </head> <body> <div class="back"> <div class="cat"></div> <div class="building1"></div> <div class="building2"></div> <div class="building7"></div> </div> </body> </html>
2.5 여러분을 위한 과제
이미지를 활용하여 좀 더 다양한 스토리 애니메이션을 만들어보세요. 친구들도(양, 여우, 토끼) 만나게 하시고, 나무도 배치하며, 보다 많은 건물들도 배치해보십시오.
뒤편에 JS까지 공부하시고 다시 이 챕터로 돌아와 공부해보시면 좀 더 많은 도움이 되실 것입니다.