
animation
animation: name duration timing-function delay iteration-count direction fill-mode play-state ;
- transition이 자동발동(self-invoking transition) 하도록 하고 싶다면 CSS animation을 사용한다.
- animation효과는 HTML 요소에 적용되는 스타일을 다른 스타일로 부드럽게 변화시킨다.
- 애니메이션을 나타내는 스타일과 애니메이션의 sequance를 나타내는 복수의 (
@keyframes
)들로 이루어진다.
- 비교적 작은 효과나 CSS만으로도 충분한 효과를 볼 수 있는 것은 CSS를 사용한다.
- 세밀한 제어를 위해서는 Javascript 사용이 바람직하다. 예를 들어 바운스, 중지, 일시 중지, 되감기 또는 감속과 같은 고급 효과는 Javascript가 훨씬 유용하다.
- 여러 사항들을 고려하여 Javacript를 사용할지 CSS를 사용할지 결정하여야 한다.
프로퍼티 | 설명 | 기본값 |
---|
animation-name | @keyframes 애니메이션 이름을 지정한다 | |
animation-duration | 한 싸이클의 애니메이션에 소요되는 시간을 초 단위(s) 또는 밀리 초 단위(ms)로 지정한다 | 0s |
animation-timing-function | 애니메이션 효과를 위한 타이밍 함수를 지정한다 | ease |
animation-delay | 요소가 로드된 시점과 애니메이션이 실제로 시작하는 사이에 대기하는 시간을 초 단위(s) 또는 밀리 초 단위(ms)로 지정한다 | 0s |
animation-iteration-count | 애니메이션 재생 횟수를 지정한다 | 1 |
animation-direction | 애니메이션이 종료된 이후 반복될 때 진행하는 방향을 지정한다 | normal |
animation-fill-mode | 애니메이션 미실행 시( 종료 또는 대기 )요소의 스타일을 지정한다 | |
animation-play-state | 애니메이션 재생 상태( 재생 또는 중지 )를 지정한다 | running |
animation | 모든 애니메이션 프로퍼티를 한번에 지정한다 ( shorthand syntax ) | |
@keyframes
- 애니메이션의 흐름 중의 여러 시점에서 CSS 프로퍼티값을 지정할 수 있다.
div {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
animation-name: move;
animation-duration: 5s;
animation-iteration-count: infinite;
}
@keyframes move {
from {
left: 0;
}
to {
left: 300px;
}
}
- from, to 키워드를 사용하여 애니메이션의 시작과 끝 시점을 정의하였다.
@keyframes move {
0% { left: 0; }
50% { left: 100px; }
100% { left: 300px; }
}
- from, to 키워드 대신 %(퍼센트)를 사용할 수도 있다. 시작과 끝 키프레임 사이에 %단위로 키프레임을 삽입할 수 있다.
animation-name
- 애니메이션을 대표하는 임의의 이름을 부여한다.
@keyframes move {}
animation-duration
- 한 사이클의 애니메이션에 소요되는 시간을 초 단위(s) 또는 밀리 초 단위(ms)로 지정한다.
- animation-duration은 반드시 지정해야 한다. 지정하지 않는 경우 기본값 0s로 인해 어떠한 애니메이션도 실행되지 않는다.
animation-duration: .5s;
또는 animation-duration: 500ms;
animation-timing-function
- 애니메이션 효과를 위한 수치 함수를 지정한다. transition-timing-fucntion을 참조한다.
animation-delay
- 요소가 애니메이션이 실제로 시작하는 사이에 대기하는 시간을 초 단위(s) 또는 밀리 초 단위(ms)로 지정한다.
animation-delay: 2s;
animation-iteration-count
- 애니메이션 주기의 재생 횟수를 지정한다. 기본값은 1이며 infinite로 무한반복 할 수 있다.
animation-iteration-count: 3;
또는 animation-iteration-count: infinite;
animation-direction
- 애니메이션이 종료된 이후 반복될 때 진행하는 방향을 지정한다.
프로퍼티값 | 설명 |
---|
normal | 기본값으로 from(0%)에서 to(100%)방향으로 진행한다 |
reverse | to에서 from방향으로 역진행한다 |
alternate | 홀수번째는 normal로, 짝수번째는 reverse로 진행한다 |
alternate-reverse | 홀수번째는 reverse로, 짝수번째는 normal로 진행한다 |
animation-fill-mode
- 애니메이션 미실행 시(대기 또는 종료)요소의 스타일을 지정한다.
프로퍼티값 | 상태 | 설명 |
---|
none | 대기 | 시작 프레임(from)에 설정한 스타일을 적용하지 않고 대기한다 |
| 종료 | 애니메이션 실행 전 상태로 애니메이션 요소의 프로퍼티값을 되돌리고 종료한다 |
forwards | 대기 | 시작 프레임(from)에 설정한 스타일을 적용하지 않고 대기한다 |
| 종료 | 종료 프레임(to)에 설정한 스타일을 적용하고 종료한다 |
backwards | 대기 | 시작 프레임(from)에 설정한 스타일을 적용하고 대기한다 |
| 종료 | 애니메이션 실행 전 상태로 애니메이션 요소의 프로퍼티값을 되돌리고 종료한다 |
both | 대기 | 시작 프레임(from)에 설정한 스타일을 적용하고 대기한다 |
| 종료 | 종료 프레임(to)에 설정한 스타일을 적용하고 종료한다 |
animation-play-state
- 애니메이션 재생 상태를 지정한다. 기본값은
running
이다
running
또는 paused
<style>
.box {
position: relative;
width: 100px;
height: 100px;
background-color: red;
animation-name: move;
animation-duration: 5s;
animation-play-state: paused;
animation-iteration-count: infinite;
}
@keyframes move {
from {
left: 0;
}
to {
left: 300px;
}
}
</style>
</head>
<body>
<div class="box"></div>
<button class="start">start animation</button>
<button class="pause">pause animation</button>
<script>
const box = document.querySelector('.box');
document.querySelector('.start').addEventListener('click', function () {
box.style.animationPlayState = 'running';
});
document.querySelector('.pause').addEventListener('click', function () {
box.style.animationPlayState = 'paused';
});
</script>
</body>
예제
Text animation
<section>
<div class="text-effect1 effect">
<p>
<span class="text-wrapper">
<span>The 1st</span>
<span>Text effect</span>
</span>
</p>
</div>
<div class="text-effect2 effect">
<div class="top-bottom-borders"></div>
<div class="right-left-borders"></div>
<div class="text-wrapper">
<p>
<span>The 2nd</span>
<span>Text effect</span>
</p>
</div>
</div>
</section>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;800&display=swap');
* {
padding: 0;
margin: 0;
}
body {
display: flex;
height: 100vh;
flex-direction: column;
justify-content: center;
align-items: center;
}
section {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 1800px;
}
.effect {
margin: 40px;
}
span {
display: block;
font-size: calc(1.5rem + 0.5vw);
}
span:first-child {
font-family: 'Montserrat Light', sans-serif;
}
span:last-child {
font-family: 'Montserrat ExtraBold', sans-serif;
}
.text-effect1 p {
border-left: 4px solid #000;
padding-left: 20px;
transform: scaleY(0);
animation: scaleUpBorder 1s forwards cubic-bezier(0.85, 0, 0.15, 1);
overflow: hidden;
}
@keyframes scaleUpBorder {
to {
transform: scaleY(1);
}
}
.text-effect1 .text-wrapper {
transform: translateX(calc(-100% - 20px));
animation: slideTextRight 1s 0.5s forwards cubic-bezier(0.85, 0, 0.15, 1);
}
@keyframes slideTextRight {
to {
transform: translateX(0%);
}
}
.text-effect2 {
position: relative;
}
.text-effect2 .top-bottom-borders {
position: absolute;
border-top: 2px solid #000;
border-bottom: 2px solid #000;
inset: 0;
transform: scaleX(0);
animation: scaleUpHorizontally 1s forwards cubic-bezier(0.85, 0, 0.15, 1);
}
.text-effect2 .right-left-borders {
position: absolute;
border-right: 2px solid #000;
border-left: 2px solid #000;
inset: 0;
transform: scaleY(0);
animation: scaleUpVertically 1s forwards cubic-bezier(0.85, 0, 0.15, 1);
}
.text-effect2 .text-wrapper {
overflow: hidden;
}
.text-effect2 p {
text-align: center;
padding: 20px;
transform: translateY(100%);
animation: slideTextUp 1s 0.1s forwards cubic-bezier(0.85, 0, 0.15, 1);
}
@keyframes slideTextUp {
to {
transform: translateY(0%);
}
}
@keyframes scaleUpVertically {
to {
transform: scaleY(1);
}
}
@keyframes scaleUpHorizontally {
to {
transform: scaleX(1);
}
}