Toolypet
블로그로 돌아가기
CSS

CSS Animation & Transition 완벽 가이드 2026

CSS transition과 animation의 차이, 사용법, 성능 최적화까지. 부드러운 UI 인터랙션을 만드는 실전 가이드.

Toolypet Team

Toolypet Team

Development Team

8 분 읽기

CSS Animation & Transition 완벽 가이드 2026

버튼 호버 효과, 로딩 스피너, 페이지 전환... 모던 웹에서 애니메이션은 필수입니다.

CSS만으로 JavaScript 없이 부드러운 인터랙션을 만드는 방법을 알아봅니다.


Transition vs Animation

특성TransitionAnimation
트리거상태 변화 필요 (:hover 등)자동 실행 가능
키프레임시작-끝 2개무제한
반복불가무한 반복 가능
방향순방향만역방향, 교대 가능
사용간단한 상태 전환복잡한 애니메이션

CSS Transition

기본 문법

transition: property duration timing-function delay;
속성설명기본값
property전환할 속성all
duration지속 시간0s
timing-function가속 곡선ease
delay시작 지연0s

기본 예제

/* 단일 속성 */
.button {
  background: #3b82f6;
  transition: background 0.3s ease;
}

.button:hover {
  background: #2563eb;
}

/* 다중 속성 */
.card {
  transform: translateY(0);
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
  transform: translateY(-5px);
  box-shadow: 0 20px 40px rgba(0,0,0,0.2);
}

Timing Functions

/* 내장 함수 */
.ease { transition-timing-function: ease; }         /* 기본 */
.linear { transition-timing-function: linear; }     /* 일정 속도 */
.ease-in { transition-timing-function: ease-in; }   /* 느리게 시작 */
.ease-out { transition-timing-function: ease-out; } /* 느리게 끝 */
.ease-in-out { transition-timing-function: ease-in-out; }

/* 커스텀 베지어 곡선 */
.custom { transition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); }

/* 단계적 */
.steps { transition-timing-function: steps(4, end); }

인기 베지어 곡선

/* 바운스 */
.bounce { transition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55); }

/* 스무스 */
.smooth { transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); }

/* 스냅 */
.snap { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }

CSS Animation

기본 문법

@keyframes 애니메이션이름 {
  from { /* 시작 상태 */ }
  to { /* 끝 상태 */ }
}

/* 또는 */
@keyframes 애니메이션이름 {
  0% { /* 시작 */ }
  50% { /* 중간 */ }
  100% { /* 끝 */ }
}

.element {
  animation: 이름 duration timing-function delay iteration-count direction fill-mode;
}

Animation 속성

속성설명
animation-name키프레임 이름필수
animation-duration시간필수
animation-timing-function타이밍ease
animation-delay지연 시간0s
animation-iteration-count반복 횟수1, infinite
animation-direction방향normal, reverse, alternate
animation-fill-mode종료 상태none, forwards, backwards, both
animation-play-state재생 상태running, paused

실전 애니메이션 예제

1. 페이드 인

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.fade-in {
  animation: fadeIn 0.5s ease forwards;
}

/* 위에서 페이드 인 */
@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-in-down {
  animation: fadeInDown 0.5s ease forwards;
}

2. 로딩 스피너

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #e5e7eb;
  border-top-color: #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

3. 펄스 효과

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

.pulse {
  animation: pulse 2s ease-in-out infinite;
}

/* 펄스 링 */
@keyframes pulseRing {
  0% {
    transform: scale(0.8);
    opacity: 1;
  }
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

.pulse-ring {
  position: relative;
}

.pulse-ring::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 2px solid #3b82f6;
  border-radius: 50%;
  animation: pulseRing 1.5s ease-out infinite;
}

4. 바운스

@keyframes bounce {
  0%, 100% {
    transform: translateY(0);
    animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
  }
  50% {
    transform: translateY(-25%);
    animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
  }
}

.bounce {
  animation: bounce 1s infinite;
}

5. 쉐이크 (에러)

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
  20%, 40%, 60%, 80% { transform: translateX(5px); }
}

.shake {
  animation: shake 0.5s ease;
}

/* JavaScript로 트리거 */
/* element.classList.add('shake'); */

6. 타이핑 효과

@keyframes typing {
  from { width: 0; }
  to { width: 100%; }
}

@keyframes blink {
  50% { border-color: transparent; }
}

.typing {
  overflow: hidden;
  white-space: nowrap;
  border-right: 3px solid;
  width: 0;
  animation:
    typing 3s steps(30) forwards,
    blink 0.7s step-end infinite;
}

7. 스켈레톤 로딩

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

.skeleton {
  background: linear-gradient(
    90deg,
    #f0f0f0 25%,
    #e0e0e0 50%,
    #f0f0f0 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
}

Transform과 함께 사용

Transform 속성

/* 이동 */
transform: translateX(100px);
transform: translateY(50px);
transform: translate(100px, 50px);

/* 회전 */
transform: rotate(45deg);
transform: rotateX(45deg); /* 3D */
transform: rotateY(45deg); /* 3D */

/* 크기 */
transform: scale(1.5);
transform: scaleX(2);

/* 기울기 */
transform: skew(10deg);

/* 조합 */
transform: translateX(100px) rotate(45deg) scale(1.2);

3D 효과

/* 부모에 원근감 설정 */
.perspective-container {
  perspective: 1000px;
}

/* 카드 플립 */
.card-3d {
  transform-style: preserve-3d;
  transition: transform 0.6s;
}

.card-3d:hover {
  transform: rotateY(180deg);
}

.card-front, .card-back {
  backface-visibility: hidden;
}

.card-back {
  transform: rotateY(180deg);
}

성능 최적화

GPU 가속 속성

/* ✅ GPU 가속 (성능 좋음) */
transform: translateX(100px);
transform: scale(1.1);
transform: rotate(45deg);
opacity: 0.5;

/* ❌ CPU 연산 (리플로우 발생) */
left: 100px;
width: 200px;
height: 200px;
margin: 10px;

will-change

/* 애니메이션 대상에 힌트 */
.animated {
  will-change: transform, opacity;
}

/* 호버 시에만 */
.card:hover {
  will-change: transform;
}

/* 애니메이션 후 제거 권장 */

리플로우 피하기

/* ❌ 피해야 할 패턴 */
.bad {
  animation: move 1s infinite;
}
@keyframes move {
  to { left: 100px; } /* 리플로우 발생 */
}

/* ✅ 권장 패턴 */
.good {
  animation: moveGood 1s infinite;
}
@keyframes moveGood {
  to { transform: translateX(100px); } /* GPU 가속 */
}

접근성

모션 감소 설정 존중

/* 사용자가 모션 감소를 원할 때 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* 또는 선택적으로 */
@media (prefers-reduced-motion: reduce) {
  .animated {
    animation: none;
  }

  .transition {
    transition: none;
  }
}

실전 UI 패턴

버튼 호버

.button {
  background: #3b82f6;
  color: white;
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.button:hover {
  background: #2563eb;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(59,130,246,0.4);
}

.button:active {
  transform: translateY(0);
}

메뉴 드롭다운

.dropdown {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  transition: all 0.2s ease;
}

.menu:hover .dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

모달 열기

.modal-overlay {
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease;
}

.modal-overlay.active {
  opacity: 1;
  visibility: visible;
}

.modal {
  transform: scale(0.9) translateY(20px);
  transition: transform 0.3s ease;
}

.modal-overlay.active .modal {
  transform: scale(1) translateY(0);
}

순차 등장

.item {
  opacity: 0;
  transform: translateY(20px);
  animation: fadeInUp 0.5s ease forwards;
}

.item:nth-child(1) { animation-delay: 0.1s; }
.item:nth-child(2) { animation-delay: 0.2s; }
.item:nth-child(3) { animation-delay: 0.3s; }

@keyframes fadeInUp {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

FAQ

Q1: transition이 작동하지 않아요

A: 확인할 것:

  • 변경되는 속성이 애니메이션 가능한지
  • display: none에서 전환 시 작동 안 함
  • 시작 값과 끝 값이 명시되어 있는지

Q2: animation이 끝난 후 상태를 유지하려면?

A: animation-fill-mode: forwards 사용

.element {
  animation: fadeIn 1s ease forwards;
}

Q3: 성능이 나빠요

A:

  • transformopacity만 애니메이션
  • will-change 적절히 사용
  • 너무 많은 요소에 애니메이션 피하기

Q4: JavaScript와 CSS 애니메이션 중 뭐가 좋아요?

A:

  • 간단한 전환: CSS
  • 복잡한 시퀀스: JavaScript (GSAP 등)
  • 사용자 입력 반응: JavaScript
  • 자동 루프: CSS

마무리

CSS 애니메이션 핵심:

  1. Transition: 상태 변화에 반응
  2. Animation: 자동 실행, 키프레임
  3. Transform: GPU 가속, 성능 우수
  4. 타이밍: ease, cubic-bezier
  5. 접근성: prefers-reduced-motion 존중

관련 도구

도구용도
Animation 생성기키프레임 생성
Transform 생성기변환 효과
필터 생성기CSS 필터
CSSanimationtransition애니메이션UI인터랙션

저자 소개

Toolypet Team

Toolypet Team

Development Team

The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.

Web DevelopmentCSS ToolsDeveloper ToolsSEOSecurity