# CSS만으로 구현하는 Scroll-driven Animation 가이드

> Clean Markdown view of GeekNews topic #21677. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=21677](https://news.hada.io/topic?id=21677)
- GeekNews Markdown: [https://news.hada.io/topic/21677.md](https://news.hada.io/topic/21677.md)
- Type: news
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-06-27T10:30:02+09:00
- Updated: 2025-06-27T10:30:02+09:00
- Original source: [webkit.org](https://webkit.org/blog/17101/a-guide-to-scroll-driven-animations-with-just-css/)
- Points: 31
- Comments: 2

## Summary

CSS의 **animation-timeline**과 **animation-range** 속성을 이용하여, 별도의 자바스크립트 없이 스크롤 동작이나 뷰포트 진입에 따라 인터랙티브한 모션 효과를 구현할 수 있습니다. 최신 브라우저(Safari 26 beta 등)에서 지원이 확대되면서, **scroll()**, **view()** 타임라인 기반 애니메이션과 세밀한 구간 제어가 가능해졌습니다. 또한 **prefers-reduced-motion** 미디어 쿼리를 통해 모션 접근성 요구에도 유연하게 대응할 수 있습니다.

## Topic Body

- 별도의 JS나 라이브러리 없이, **CSS만으로 스크롤 연동 애니메이션** 구현 가능  
- **animation-timeline: scroll() / view()** 등 CSS 속성으로 스크롤 위치, 뷰포트 진입 등에 따라 애니메이션 진행   
- **animation-range** 속성으로 애니메이션이 뷰포트 내 어느 구간에서 시작/종료할지 상세 조절   
- 움직임에 민감한 사용자를 위해 **prefers-reduced-motion** 미디어 쿼리 활용 권장  
- Safari 26 beta부터 지원하며, **CSS 기반 스크롤 애니메이션**의 활용 폭이 크게 넓어짐  
---  
### 스크롤 기반 애니메이션의 3가지 요소  
- **Target:** 애니메이션을 적용할 대상 요소(예: 프로그레스 바, 이미지 등)  
- **Keyframes:** 스크롤에 따라 어떤 변화가 일어날지 정의(기존 CSS @keyframes와 동일)  
- **Timeline:** 애니메이션이 언제, 어떻게 진행될지 결정(시간 기반이 아닌 스크롤/뷰 기반)  
  
### CSS에서의 Timeline  
  
- 기존 CSS 애니메이션은 기본적으로 **document timeline**(시간 기반) 사용  
- **animation-timeline** 속성 도입(CSS Animations Level 2, 2023년): 시간 외에 **스크롤, 뷰포트 진입** 등 다양한 기준으로 애니메이션 진행 가능  
  
#### scroll() timeline  
  
- **scroll()** 타임라인은 사용자가 스크롤할 때만 애니메이션이 진행됨  
- 예시: 하단 프로그레스 바가 스크롤에 따라 왼쪽에서 오른쪽으로 차오르는 효과  
  ```css  
  footer::after {  
    content: "";  
    height: 1em;  
    width: 100%;  
    background: rgba(254, 178, 16, 1);  
    left: 0;  
    bottom: 0;  
    position: fixed;  
    animation: grow-progress linear;  
    animation-timeline: scroll();  
  }  
  @keyframes grow-progress {  
    from { transform: scaleX(0); }  
    to { transform: scaleX(1); }  
  }  
  ```  
- **animation-timeline**은 **animation** 속성 다음에 정의해야 정상 동작  
  
#### 모션 접근성 고려  
  
- 모션 민감 사용자 보호를 위해 **prefers-reduced-motion** 미디어 쿼리 사용 권장  
  ```css  
  @media not (prefers-reduced-motion) {  
      /* 애니메이션 코드 */  
  }  
  ```  
  
### view() timeline  
  
- **view()** 타임라인은 타깃 요소가 **뷰포트에 등장할 때** 애니메이션이 시작됨  
- 예시: 스크롤 시 이미지가 오른쪽에서 슬라이드 및 페이드인  
  ```css  
  @keyframes slideIn {  
    0% {  
      transform: translateX(100%);  
      opacity: 0;  
    }  
    100% {  
      transform: translateX(0%);  
      opacity: 1;  
    }  
  }  
  img {  
    animation: slideIn;  
    animation-timeline: view();  
  }  
  ```  
  
#### animation-range로 진행 구간 제어  
  
* 기본적으로 animation-range는 0%(뷰포트 진입)\~100%(완전 이탈)  
* 예: 뷰포트의 50% 구간까지만 애니메이션 진행  
  ```css  
  img {  
    animation: slideIn;  
    animation-timeline: view();  
    animation-range: 0% 50%;  
  }  
  ```  
  
* 사용자 경험을 위해 적절한 range 값 설정 필요  
* 모션 접근성 고려 시, **prefers-reduced-motion**와 함께 사용  
  ```css  
  @media not (prefers-reduced-motion) {  
    img {  
      animation: slideIn;  
      animation-timeline: view();  
      animation-range: 0% 50%;  
    }  
  }  
  ```  
  
### 고급 활용 및 다음 단계  
  
* scroll(), view()는 함수로, scroller 요소(기본: nearest)나 축(block, inline, x, y) 등 다양한 옵션 지정 가능  
* animation-range, entry/exit 등으로 보다 섬세한 UX 구현 가능  
* Safari 26 beta 등 최신 브라우저에서 우선 지원, 앞으로 점차 표준화 및 지원 확대 예정

## Comments



### Comment 40748

- Author: shakespeare
- Created: 2025-06-29T16:30:41+09:00
- Points: 1

animation-timeline만으로 구현할 수 있네요. 신기하네요!

### Comment 40685

- Author: [hidden]
- Created: 2025-06-27T11:52:09+09:00
- Points: 1

[숨김 처리된 댓글입니다]
