
AOS는 스크롤 위치에 따라 요소에 fade, slide, zoom 같은 애니메이션을 자동으로 적용해주는 자바스크립트 라이브러리입니다. CDN 링크 두 줄만 추가하고 AOS.init()을 호출한 뒤, 애니메이션을 원하는 요소에 data-aos="fade-up" 같은 속성만 붙이면 바로 동작합니다.
AOS(Animate On Scroll)란?
AOS는 요소가 뷰포트(화면에 보이는 영역)에 들어올 때 미리 정의된 CSS 애니메이션을 자동으로 트리거해주는 경량 라이브러리입니다. 인터섹션옵저버나 스크롤 이벤트를 직접 구현하지 않아도 되고, jQuery 같은 별도 의존성 없이도 동작해서 랜딩 페이지나 포트폴리오 사이트에 스크롤 인터랙션을 빠르게 넣을 때 많이 쓰입니다.
설치 방법
1. CDN으로 설치
가장 빠른 방법은 head 태그에 스타일시트를, body 태그 끝부분에 스크립트를 추가하는 것입니다.
html
<head>
<link rel="stylesheet" href="https://unpkg.com/aos@2.3.4/dist/aos.css" />
</head>
<body>
...
<script src="https://unpkg.com/aos@2.3.4/dist/aos.js"></script>
<script>
AOS.init();
</script>
</body>
참고로 aos@next 같은 태그는 버전이 계속 바뀌기 때문에, 실제로 위처럼 특정 버전(예: 2.3.4)을 명시해서 쓰시는 걸 권해드립니다. 버전이 고정되지 않으면 라이브러리 업데이트로 갑자기 애니메이션 동작이 달라질 수 있습니다.
2. 패키지 매니저로 설치 (npm/yarn)
bash
npm install aos
# 또는
yarn add aos
javascript
import AOS from 'aos';
import 'aos/dist/aos.css';
AOS.init();
3. React에서 사용하기
React는 컴포넌트가 마운트될 때 초기화해줘야 하므로 useEffect로 감싸서 호출합니다.
jsx
import React, { useEffect } from "react";
import AOS from "aos";
import "aos/dist/aos.css";
function App() {
useEffect(() => {
AOS.init({ duration: 800, once: true });
}, []);
return (
<div>
<p data-aos="fade-up">스크롤하면 나타납니다</p>
</div>
);
}
기본 사용법
애니메이션을 적용하고 싶은 요소에 data-aos 속성만 추가하면 됩니다. 단, AOS는 블록 태그(div, p, section 등)에만 적용되고 인라인 태그(span, a 등)에는 적용되지 않는다는 점을 꼭 기억해두세요.
html
<div data-aos="fade-up">이 요소는 아래에서 위로 페이드인 됩니다</div>
<div
data-aos="fade-up"
data-aos-offset="200"
data-aos-delay="50"
data-aos-duration="1000"
data-aos-easing="ease-in-out"
data-aos-once="false"
data-aos-anchor-placement="top-center"
>
여러 옵션을 조합한 예시입니다
</div>

주요 속성 & 애니메이션 종류
| 속성 | 설명 | 기본값 |
| data-aos | 적용할 애니메이션 이름 | – |
| data-aos-easing | 애니메이션 속도 곡선 | ease |
| data-aos-delay | 애니메이션 시작 전 대기시간(ms) | 0 |
| data-aos-duration | 애니메이션 재생시간(ms) | 400 |
| data-aos-offset | 애니메이션이 시작될 스크롤 위치(px) | 120 |
| data-aos-anchor-placement | 애니메이션 기준 위치 | top-bottom |
| data-aos-once | 한 번만 실행할지 여부 | FALSE |
| data-aos-mirror | 위로 스크롤할 때도 반대로 애니메이션할지 | FALSE |
대표 애니메이션 종류: fade, fade-up, fade-down, fade-left, fade-right / flip-up, flip-down, flip-left, flip-right / slide-up, slide-down, slide-left, slide-right / zoom-in, zoom-out (각각 -up, -down, -left, -right 조합 가능)
동적 콘텐츠에서 AOS가 안 먹힐 때
가장 많이 겪는 문제가 바로 이겁니다. API로 데이터를 받아와서 나중에 DOM에 추가된 요소는 AOS가 처음 초기화될 때 이미 스캔을 끝낸 뒤라 애니메이션이 적용되지 않습니다. 이럴 땐 새로 추가된 요소를 인식시키기 위해 새로고침 함수를 호출해야 합니다.
javascript
// 위치 값만 다시 계산 (요소 추가/삭제는 없고 레이아웃만 바뀐 경우)
AOS.refresh();
// 요소를 처음부터 다시 스캔 (새로운 data-aos 요소가 추가된 경우)
AOS.refreshHard();
무한스크롤이나 API로 리스트를 계속 추가하는 화면이라면, 새 데이터를 렌더링한 직후에 AOS.refreshHard()를 호출해주셔야 새로 추가된 요소에도 애니메이션이 붙습니다. 저도 처음 무한스크롤 페이지에 AOS를 붙였을 때 첫 화면 요소만 애니메이션 되고 스크롤로 추가된 카드들은 그냥 뙇 나타나서 한참 헤맸는데, refreshHard() 한 줄 추가하니 바로 해결됐습니다.

React/Vue에서 자주 겪는 문제와 해결법
- 컴포넌트가 리렌더링될 때마다 애니메이션이 다시 실행되는 문제:
useEffect의 의존성 배열을 빈 배열([])로 둬서 최초 마운트 시에만AOS.init()이 실행되도록 해야 합니다. - 라우팅 후 페이지 이동 시 애니메이션이 안 먹히는 문제: SPA에서는 페이지 전환이 실제 새로고침이 아니기 때문에, 라우트가 바뀔 때마다
AOS.refresh()를 호출해주는 게 안전합니다. - 조건부 렌더링된 요소에 적용이 안 되는 문제: 요소가 렌더링된 직후 타이밍에
AOS.refreshHard()를 호출해야 새로 마운트된 요소를 인식합니다.
자주 묻는 질문(FAQ)
Q1. 모바일에서는 애니메이션이 안 보이는데 왜 그런가요?
기본 설정에서는 모바일에서도 동작해야 하지만, AOS.init({ disable: 'mobile' })처럼 옵션이 켜져 있으면 모바일에서 비활성화됩니다. 초기화 옵션을 다시 확인해보세요.
Q2. 무한스크롤로 추가되는 콘텐츠에는 왜 애니메이션이 안 붙나요?
AOS는 처음 초기화 시점의 DOM만 스캔하기 때문입니다. 새 요소가 추가된 직후 AOS.refreshHard()를 호출해주시면 해결됩니다.
Q3. AOS 말고 다른 스크롤 애니메이션 라이브러리와 차이는 뭔가요?
ScrollMagic 같은 라이브러리는 더 복잡한 시퀀스 애니메이션에 강하지만 설정이 까다롭고, AOS는 속성 하나로 빠르게 적용할 수 있어서 간단한 등장 애니메이션에는 AOS가 훨씬 가볍고 편합니다.
Q4. 최신 버전은 어떻게 확인하나요?
npm 패키지 페이지(npmjs.com/package/aos)나 깃허브 릴리즈 탭에서 최신 버전을 확인할 수 있습니다. CDN을 쓰신다면 unpkg 링크의 버전 번호를 최신으로 맞춰서 명시해주시는 게 안전합니다.