scroll-reveal-libraries by freshtechbro/claudedesignskills
npx skills add https://github.com/freshtechbro/claudedesignskills --skill scroll-reveal-libraries本技能涵盖 AOS(滚动时动画),这是一个轻量级的 CSS 驱动库,用于实现滚动触发的动画。AOS 擅长在元素进入视口时激活简单的淡入淡出、滑动和缩放效果。
主要特性:
适用场景:
不适用场景:
CDN(最快):
<head>
<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
</head>
<body>
<!-- 包含 data-aos 属性的内容 -->
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script>
AOS.init();
</script>
</body>
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
NPM/Yarn(推荐):
npm install aos@next
# 或
yarn add aos@next
import AOS from 'aos';
import 'aos/dist/aos.css';
AOS.init();
使用 data-aos 属性应用动画:
<!-- 淡入 -->
<div data-aos="fade-in">内容</div>
<!-- 向上淡入 -->
<div data-aos="fade-up">内容</div>
<!-- 从右侧滑入 -->
<div data-aos="slide-left">内容</div>
<!-- 放大 -->
<div data-aos="zoom-in">内容</div>
全局配置:
AOS.init({
// 动画设置
duration: 800, // 动画持续时间(毫秒):0-3000
delay: 0, // 动画开始前的延迟(毫秒):0-3000
offset: 120, // 触发点的偏移量(像素)
easing: 'ease', // 缓动函数
once: false, // 仅动画一次(true)或每次滚动都动画(false)
mirror: false, // 滚动经过时反向动画
// 位置
anchorPlacement: 'top-bottom', // 哪个位置触发动画
// 性能
disable: false, // 在移动设备/平板电脑上禁用
startEvent: 'DOMContentLoaded', // 初始化事件
debounceDelay: 50, // 窗口调整大小防抖
throttleDelay: 99 // 滚动节流
});
元素级覆盖:
<div
data-aos="fade-up"
data-aos-duration="1000"
data-aos-delay="200"
data-aos-offset="50"
data-aos-easing="ease-in-out"
data-aos-once="true"
data-aos-mirror="true"
data-aos-anchor-placement="center-bottom"
>
自定义配置的元素
</div>
<section class="hero">
<!-- 错开的标题文字 -->
<h1
data-aos="fade-down"
data-aos-duration="800"
>
欢迎来到未来
</h1>
<!-- 延迟的子标题 -->
<p
data-aos="fade-up"
data-aos-delay="200"
data-aos-duration="600"
>
将您的想法变为现实
</p>
<!-- 行动号召按钮 -->
<button
data-aos="zoom-in"
data-aos-delay="400"
data-aos-duration="500"
>
开始使用
</button>
</section>
<div class="features-grid">
<!-- 使用递增延迟错开卡片 -->
<div
class="feature-card"
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="0"
>
<h3>功能 1</h3>
<p>描述...</p>
</div>
<div
class="feature-card"
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="100"
>
<h3>功能 2</h3>
<p>描述...</p>
</div>
<div
class="feature-card"
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="200"
>
<h3>功能 3</h3>
<p>描述...</p>
</div>
</div>
<!-- 内容从左侧进入 -->
<div class="section">
<div
class="content"
data-aos="slide-right"
data-aos-duration="800"
>
<h2>区域标题</h2>
<p>内容从左侧滑入...</p>
</div>
<img
src="image1.jpg"
data-aos="fade-left"
data-aos-delay="200"
/>
</div>
<!-- 内容从右侧进入 -->
<div class="section reverse">
<img
src="image2.jpg"
data-aos="fade-right"
/>
<div
class="content"
data-aos="slide-left"
data-aos-duration="800"
data-aos-delay="200"
>
<h2>区域标题</h2>
<p>内容从右侧滑入...</p>
</div>
</div>
<div class="testimonials">
<div
class="testimonial"
data-aos="zoom-in"
data-aos-duration="500"
>
<blockquote>"令人惊叹的产品!"</blockquote>
<cite>- 张三</cite>
</div>
<div
class="testimonial"
data-aos="zoom-in"
data-aos-duration="500"
data-aos-delay="100"
>
<blockquote>"超出预期"</blockquote>
<cite>- 李四</cite>
</div>
</div>
根据其他元素的滚动位置触发动画:
<!-- 固定侧边栏根据主内容滚动进行动画 -->
<div class="main-content">
<div id="trigger-point" data-aos-id="sidebar-trigger">
<!-- 内容 -->
</div>
</div>
<aside
class="sidebar"
data-aos="fade-left"
data-aos-anchor="#trigger-point"
>
侧边栏内容
</aside>
<div class="animation-sequence">
<!-- 步骤 1:标题 -->
<h2
data-aos="fade-down"
data-aos-duration="600"
data-aos-delay="0"
>
我们的流程
</h2>
<!-- 步骤 2:描述 -->
<p
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="200"
>
遵循这些简单步骤
</p>
<!-- 步骤 3-5:流程卡片 -->
<div
class="process-step"
data-aos="flip-left"
data-aos-delay="400"
>
步骤 1
</div>
<div
class="process-step"
data-aos="flip-left"
data-aos-delay="600"
>
步骤 2
</div>
<div
class="process-step"
data-aos="flip-left"
data-aos-delay="800"
>
步骤 3
</div>
</div>
<div class="gallery">
<img
src="photo1.jpg"
data-aos="zoom-in-up"
data-aos-duration="800"
/>
<img
src="photo2.jpg"
data-aos="zoom-in-up"
data-aos-duration="800"
data-aos-delay="100"
/>
<img
src="photo3.jpg"
data-aos="zoom-in-up"
data-aos-duration="800"
data-aos-delay="200"
/>
</div>
基本设置:
import { useEffect } from 'react';
import AOS from 'aos';
import 'aos/dist/aos.css';
function App() {
useEffect(() => {
AOS.init({
duration: 800,
once: true,
offset: 100
});
}, []);
return (
<div>
<h1 data-aos="fade-down">欢迎</h1>
<p data-aos="fade-up">内容在这里</p>
</div>
);
}
路由变化时刷新:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import AOS from 'aos';
function App() {
const location = useLocation();
useEffect(() => {
AOS.init({ duration: 800 });
}, []);
// 路由变化时刷新 AOS
useEffect(() => {
AOS.refresh();
}, [location]);
return <Routes>{/* 路由 */}</Routes>;
}
动态内容更新:
import { useState, useEffect } from 'react';
import AOS from 'aos';
function DynamicList() {
const [items, setItems] = useState([]);
useEffect(() => {
AOS.init();
}, []);
const addItem = () => {
setItems([...items, { id: Date.now(), text: '新项目' }]);
// 刷新 AOS 以检测新元素
setTimeout(() => AOS.refresh(), 50);
};
return (
<div>
<button onClick={addItem}>添加项目</button>
<ul>
{items.map((item) => (
<li key={item.id} data-aos="fade-in">
{item.text}
</li>
))}
</ul>
</div>
);
}
组件包装器模式:
import AOS from 'aos';
import 'aos/dist/aos.css';
function AnimatedSection({ children, animation = "fade-up", delay = 0, ...props }) {
return (
<div
data-aos={animation}
data-aos-delay={delay}
{...props}
>
{children}
</div>
);
}
// 用法
<AnimatedSection animation="slide-right" delay={200}>
<h2>动画内容</h2>
</AnimatedSection>
<template>
<div>
<h1 data-aos="fade-down">Vue + AOS</h1>
<div
v-for="(item, index) in items"
:key="item.id"
data-aos="fade-up"
:data-aos-delay="index * 100"
>
{{ item.text }}
</div>
</div>
</template>
<script>
import AOS from 'aos';
import 'aos/dist/aos.css';
export default {
mounted() {
AOS.init({ duration: 800 });
},
updated() {
// 组件更新时刷新
this.$nextTick(() => {
AOS.refresh();
});
},
data() {
return {
items: [/*...*/]
};
}
};
</script>
// pages/_app.js
import { useEffect } from 'react';
import AOS from 'aos';
import 'aos/dist/aos.css';
function MyApp({ Component, pageProps }) {
useEffect(() => {
AOS.init({
duration: 800,
once: true
});
}, []);
return <Component {...pageProps} />;
}
export default MyApp;
// pages/index.js
export default function Home() {
return (
<main>
<h1 data-aos="fade-down">Next.js + AOS</h1>
<p data-aos="fade-up">带有动画的服务端渲染内容</p>
</main>
);
}
AOS.init({
disable: 'mobile', // 在移动设备上禁用
// 或使用函数进行自定义逻辑
disable: function() {
return window.innerWidth < 768;
}
});
once 以获得更好性能AOS.init({
once: true, // 仅动画一次(性能更好)
mirror: false // 不反向动画
});
AOS.init({
throttleDelay: 99, // 滚动事件节流(默认)
debounceDelay: 50 // 调整大小事件防抖(默认)
});
AOS.init({
disableMutationObserver: true // 为完全静态的内容禁用
});
<!-- 更简单的动画性能更好 -->
<div data-aos="fade-in">简单淡入</div>
<!-- 复杂的动画可能导致卡顿 -->
<div data-aos="flip-left">复杂翻转</div>
if ('requestIdleCallback' in window) {
requestIdleCallback(() => {
AOS.init({ duration: 800 });
});
} else {
AOS.init({ duration: 800 });
}
问题:动态添加的新元素没有动画效果。
解决方案:调用 AOS.refresh() 或 AOS.refreshHard():
// 将元素添加到 DOM 后
const newElement = document.createElement('div');
newElement.setAttribute('data-aos', 'fade-in');
container.appendChild(newElement);
// 刷新 AOS
AOS.refresh(); // 重新计算位置
// 或
AOS.refreshHard(); // 完全重新初始化
问题:AOS 在首次渲染或路由变化时未检测到元素。
解决方案:在 useEffect 中初始化并在路由/内容变化时刷新:
useEffect(() => {
AOS.init();
return () => AOS.refresh(); // 清理
}, []);
useEffect(() => {
AOS.refresh(); // 路由变化时刷新
}, [location.pathname]);
问题:页面滚动时,由于许多动画元素导致感觉卡顿。
解决方案:减少动画元素并使用 once: true:
AOS.init({
once: true, // 仅动画一次
disable: window.innerWidth < 768 // 在移动设备上禁用
});
问题:自定义 CSS 干扰了 AOS 动画。
解决方案:使用更具体的选择器并避免 !important:
/* 不好:与 AOS 冲突 */
div {
opacity: 1 !important;
}
/* 好:具体的选择器 */
.my-content > div {
/* 样式 */
}
问题:动画在意外滚动位置触发。
解决方案:理解锚点放置选项:
// 当元素顶部到达视口底部时触发
data-aos-anchor-placement="top-bottom"
// 当元素中心到达视口中心时触发
data-aos-anchor-placement="center-center"
// 当元素底部到达视口顶部时触发
data-aos-anchor-placement="bottom-top"
问题:超过 3000 毫秒的值不起作用。
解决方案:添加自定义 CSS 以延长持续时间:
body[data-aos-duration='4000'] [data-aos],
[data-aos][data-aos][data-aos-duration='4000'] {
transition-duration: 4000ms;
}
<div data-aos="fade-in" data-aos-duration="4000">
长动画
</div>
fade-in - 简单淡入fade-up - 从底部淡入fade-down - 从顶部淡入fade-left - 从右侧淡入fade-right - 从左侧淡入fade-up-right - 对角线淡入fade-up-left - 对角线淡入fade-down-right - 对角线淡入fade-down-left - 对角线淡入slide-up - 从底部滑入slide-down - 从顶部滑入slide-left - 从右侧滑入slide-right - 从左侧滑入zoom-in - 放大zoom-in-up - 从底部放大zoom-in-down - 从顶部放大zoom-in-left - 从右侧放大zoom-in-right - 从左侧放大zoom-out - 缩小zoom-out-up - 缩小到顶部zoom-out-down - 缩小到底部zoom-out-left - 缩小到左侧zoom-out-right - 缩小到右侧flip-up - 从底部翻转flip-down - 从顶部翻转flip-left - 从右侧翻转flip-right - 从左侧翻转使用 CSS 创建自定义动画:
[data-aos="custom-slide-bounce"] {
opacity: 0;
transform: translateY(100px);
transition-property: transform, opacity;
}
[data-aos="custom-slide-bounce"].aos-animate {
opacity: 1;
transform: translateY(0);
animation: bounce 0.5s;
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
<div data-aos="custom-slide-bounce">
自定义动画
</div>
| 特性 | AOS | GSAP ScrollTrigger |
|---|---|---|
| 复杂度 | 简单,基于数据属性 | 高级,JavaScript API |
| 使用场景 | 简单显示 | 复杂时间线 |
| 文件大小 | ~13KB | ~27KB (GSAP) + ScrollTrigger |
| 性能 | CSS 驱动 | JavaScript 驱动 |
| 学习曲线 | 分钟级 | 小时级 |
| 自定义 | 有限 | 广泛 |
| 最适合 | 营销页面 | 交互式体验 |
使用 AOS 当:
使用 GSAP ScrollTrigger 当:
scripts/aos_generator.py - 生成 AOS HTML 样板文件scripts/config_builder.py - 构建 AOS 配置references/aos_api.md - 完整的 AOS API 参考references/animation_catalog.md - 所有内置动画及演示references/integration_patterns.md - 框架集成指南assets/starter_aos/ - 完整的 AOS 入门模板assets/examples/ - 生产就绪的模式每周安装次数
82
代码仓库
GitHub 星标数
11
首次出现
2026年2月27日
安全审计
安装于
opencode82
cursor80
github-copilot80
codex80
amp80
cline80
This skill covers AOS (Animate On Scroll), a lightweight CSS-driven library for scroll-triggered animations. AOS excels at simple fade, slide, and zoom effects activated when elements enter the viewport.
Key Features :
When to Use :
When NOT to Use :
CDN (Quickest) :
<head>
<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
</head>
<body>
<!-- Content with data-aos attributes -->
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script>
AOS.init();
</script>
</body>
NPM/Yarn (Recommended) :
npm install aos@next
# or
yarn add aos@next
import AOS from 'aos';
import 'aos/dist/aos.css';
AOS.init();
Apply animations using the data-aos attribute:
<!-- Fade in -->
<div data-aos="fade-in">Content</div>
<!-- Fade up -->
<div data-aos="fade-up">Content</div>
<!-- Slide from right -->
<div data-aos="slide-left">Content</div>
<!-- Zoom in -->
<div data-aos="zoom-in">Content</div>
Global Configuration :
AOS.init({
// Animation settings
duration: 800, // Animation duration (ms): 0-3000
delay: 0, // Delay before animation (ms): 0-3000
offset: 120, // Offset from trigger point (px)
easing: 'ease', // Easing function
once: false, // Animate only once (true) or every time (false)
mirror: false, // Animate out when scrolling past
// Placement
anchorPlacement: 'top-bottom', // Which position triggers animation
// Performance
disable: false, // Disable on mobile/tablet
startEvent: 'DOMContentLoaded', // Initialization event
debounceDelay: 50, // Window resize debounce
throttleDelay: 99 // Scroll throttle
});
Per-Element Overrides :
<div
data-aos="fade-up"
data-aos-duration="1000"
data-aos-delay="200"
data-aos-offset="50"
data-aos-easing="ease-in-out"
data-aos-once="true"
data-aos-mirror="true"
data-aos-anchor-placement="center-bottom"
>
Custom configured element
</div>
<section class="hero">
<!-- Staggered heading words -->
<h1
data-aos="fade-down"
data-aos-duration="800"
>
Welcome to the Future
</h1>
<!-- Delayed subheading -->
<p
data-aos="fade-up"
data-aos-delay="200"
data-aos-duration="600"
>
Transform your ideas into reality
</p>
<!-- CTA button -->
<button
data-aos="zoom-in"
data-aos-delay="400"
data-aos-duration="500"
>
Get Started
</button>
</section>
<div class="features-grid">
<!-- Stagger cards with increasing delays -->
<div
class="feature-card"
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="0"
>
<h3>Feature 1</h3>
<p>Description...</p>
</div>
<div
class="feature-card"
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="100"
>
<h3>Feature 2</h3>
<p>Description...</p>
</div>
<div
class="feature-card"
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="200"
>
<h3>Feature 3</h3>
<p>Description...</p>
</div>
</div>
<!-- Content from left -->
<div class="section">
<div
class="content"
data-aos="slide-right"
data-aos-duration="800"
>
<h2>Section Title</h2>
<p>Content slides in from left...</p>
</div>
<img
src="image1.jpg"
data-aos="fade-left"
data-aos-delay="200"
/>
</div>
<!-- Content from right -->
<div class="section reverse">
<img
src="image2.jpg"
data-aos="fade-right"
/>
<div
class="content"
data-aos="slide-left"
data-aos-duration="800"
data-aos-delay="200"
>
<h2>Section Title</h2>
<p>Content slides in from right...</p>
</div>
</div>
<div class="testimonials">
<div
class="testimonial"
data-aos="zoom-in"
data-aos-duration="500"
>
<blockquote>"Amazing product!"</blockquote>
<cite>- John Doe</cite>
</div>
<div
class="testimonial"
data-aos="zoom-in"
data-aos-duration="500"
data-aos-delay="100"
>
<blockquote>"Exceeded expectations"</blockquote>
<cite>- Jane Smith</cite>
</div>
</div>
Trigger animations based on a different element's scroll position:
<!-- Fixed sidebar animates based on main content scroll -->
<div class="main-content">
<div id="trigger-point" data-aos-id="sidebar-trigger">
<!-- Content -->
</div>
</div>
<aside
class="sidebar"
data-aos="fade-left"
data-aos-anchor="#trigger-point"
>
Sidebar content
</aside>
<div class="animation-sequence">
<!-- Step 1: Heading -->
<h2
data-aos="fade-down"
data-aos-duration="600"
data-aos-delay="0"
>
Our Process
</h2>
<!-- Step 2: Description -->
<p
data-aos="fade-up"
data-aos-duration="600"
data-aos-delay="200"
>
Follow these simple steps
</p>
<!-- Step 3-5: Process cards -->
<div
class="process-step"
data-aos="flip-left"
data-aos-delay="400"
>
Step 1
</div>
<div
class="process-step"
data-aos="flip-left"
data-aos-delay="600"
>
Step 2
</div>
<div
class="process-step"
data-aos="flip-left"
data-aos-delay="800"
>
Step 3
</div>
</div>
<div class="gallery">
<img
src="photo1.jpg"
data-aos="zoom-in-up"
data-aos-duration="800"
/>
<img
src="photo2.jpg"
data-aos="zoom-in-up"
data-aos-duration="800"
data-aos-delay="100"
/>
<img
src="photo3.jpg"
data-aos="zoom-in-up"
data-aos-duration="800"
data-aos-delay="200"
/>
</div>
Basic Setup :
import { useEffect } from 'react';
import AOS from 'aos';
import 'aos/dist/aos.css';
function App() {
useEffect(() => {
AOS.init({
duration: 800,
once: true,
offset: 100
});
}, []);
return (
<div>
<h1 data-aos="fade-down">Welcome</h1>
<p data-aos="fade-up">Content here</p>
</div>
);
}
Refreshing on Route Changes :
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import AOS from 'aos';
function App() {
const location = useLocation();
useEffect(() => {
AOS.init({ duration: 800 });
}, []);
// Refresh AOS on route change
useEffect(() => {
AOS.refresh();
}, [location]);
return <Routes>{/* routes */}</Routes>;
}
Dynamic Content Updates :
import { useState, useEffect } from 'react';
import AOS from 'aos';
function DynamicList() {
const [items, setItems] = useState([]);
useEffect(() => {
AOS.init();
}, []);
const addItem = () => {
setItems([...items, { id: Date.now(), text: 'New Item' }]);
// Refresh AOS to detect new elements
setTimeout(() => AOS.refresh(), 50);
};
return (
<div>
<button onClick={addItem}>Add Item</button>
<ul>
{items.map((item) => (
<li key={item.id} data-aos="fade-in">
{item.text}
</li>
))}
</ul>
</div>
);
}
Component Wrapper Pattern :
import AOS from 'aos';
import 'aos/dist/aos.css';
function AnimatedSection({ children, animation = "fade-up", delay = 0, ...props }) {
return (
<div
data-aos={animation}
data-aos-delay={delay}
{...props}
>
{children}
</div>
);
}
// Usage
<AnimatedSection animation="slide-right" delay={200}>
<h2>Animated Content</h2>
</AnimatedSection>
<template>
<div>
<h1 data-aos="fade-down">Vue + AOS</h1>
<div
v-for="(item, index) in items"
:key="item.id"
data-aos="fade-up"
:data-aos-delay="index * 100"
>
{{ item.text }}
</div>
</div>
</template>
<script>
import AOS from 'aos';
import 'aos/dist/aos.css';
export default {
mounted() {
AOS.init({ duration: 800 });
},
updated() {
// Refresh when component updates
this.$nextTick(() => {
AOS.refresh();
});
},
data() {
return {
items: [/*...*/]
};
}
};
</script>
// pages/_app.js
import { useEffect } from 'react';
import AOS from 'aos';
import 'aos/dist/aos.css';
function MyApp({ Component, pageProps }) {
useEffect(() => {
AOS.init({
duration: 800,
once: true
});
}, []);
return <Component {...pageProps} />;
}
export default MyApp;
// pages/index.js
export default function Home() {
return (
<main>
<h1 data-aos="fade-down">Next.js + AOS</h1>
<p data-aos="fade-up">Server-side rendered content with animations</p>
</main>
);
}
AOS.init({
disable: 'mobile', // Disable on mobile
// Or use function for custom logic
disable: function() {
return window.innerWidth < 768;
}
});
AOS.init({
once: true, // Animate only once (better performance)
mirror: false // Don't animate out
});
AOS.init({
throttleDelay: 99, // Scroll event throttle (default)
debounceDelay: 50 // Resize event debounce (default)
});
AOS.init({
disableMutationObserver: true // Disable for fully static content
});
<!-- Simpler animations perform better -->
<div data-aos="fade-in">Simple fade</div>
<!-- Complex animations may cause jank -->
<div data-aos="flip-left">Complex flip</div>
if ('requestIdleCallback' in window) {
requestIdleCallback(() => {
AOS.init({ duration: 800 });
});
} else {
AOS.init({ duration: 800 });
}
Problem : New elements don't animate after being added dynamically.
Solution : Call AOS.refresh() or AOS.refreshHard():
// After adding elements to DOM
const newElement = document.createElement('div');
newElement.setAttribute('data-aos', 'fade-in');
container.appendChild(newElement);
// Refresh AOS
AOS.refresh(); // Recalculate positions
// or
AOS.refreshHard(); // Reinitialize completely
Problem : AOS doesn't detect elements on first render or route changes.
Solution : Initialize in useEffect and refresh on route/content changes:
useEffect(() => {
AOS.init();
return () => AOS.refresh(); // Cleanup
}, []);
useEffect(() => {
AOS.refresh(); // Refresh on route change
}, [location.pathname]);
Problem : Page scrolling feels janky with many animated elements.
Solution : Reduce animated elements and use once: true:
AOS.init({
once: true, // Animate only once
disable: window.innerWidth < 768 // Disable on mobile
});
Problem : Custom CSS interferes with AOS animations.
Solution : Use more specific selectors and avoid !important:
/* Bad: Conflicts with AOS */
div {
opacity: 1 !important;
}
/* Good: Specific selector */
.my-content > div {
/* styles */
}
Problem : Animations trigger at unexpected scroll positions.
Solution : Understand anchor placement options:
// Triggers when element's top hits viewport bottom
data-aos-anchor-placement="top-bottom"
// Triggers when element's center hits viewport center
data-aos-anchor-placement="center-center"
// Triggers when element's bottom hits viewport top
data-aos-anchor-placement="bottom-top"
Problem : Values above 3000ms don't work.
Solution : Add custom CSS for extended durations:
body[data-aos-duration='4000'] [data-aos],
[data-aos][data-aos][data-aos-duration='4000'] {
transition-duration: 4000ms;
}
<div data-aos="fade-in" data-aos-duration="4000">
Long animation
</div>
fade-in - Simple fade infade-up - Fade in from bottomfade-down - Fade in from topfade-left - Fade in from rightfade-right - Fade in from leftfade-up-right - Diagonal fadefade-up-left - Diagonal fadefade-down-right - Diagonal fadefade-down-left - Diagonal fadeslide-up - Slide from bottomslide-down - Slide from topslide-left - Slide from rightslide-right - Slide from leftzoom-in - Zoom inzoom-in-up - Zoom in from bottomzoom-in-down - Zoom in from topzoom-in-left - Zoom in from rightzoom-in-right - Zoom in from leftzoom-out - Zoom outzoom-out-up - Zoom out to topzoom-out-down - Zoom out to bottomzoom-out-left - Zoom out to leftzoom-out-right - Zoom out to rightflip-up - Flip from bottomflip-down - Flip from topflip-left - Flip from rightflip-right - Flip from leftCreate custom animations with CSS:
[data-aos="custom-slide-bounce"] {
opacity: 0;
transform: translateY(100px);
transition-property: transform, opacity;
}
[data-aos="custom-slide-bounce"].aos-animate {
opacity: 1;
transform: translateY(0);
animation: bounce 0.5s;
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
<div data-aos="custom-slide-bounce">
Custom animation
</div>
| Feature | AOS | GSAP ScrollTrigger |
|---|---|---|
| Complexity | Simple, data-attribute based | Advanced, JavaScript API |
| Use Case | Simple reveals | Complex timelines |
| File Size | ~13KB | ~27KB (GSAP) + ScrollTrigger |
| Performance | CSS-driven | JavaScript-driven |
| Learning Curve | Minutes | Hours |
| Customization | Limited | Extensive |
| Best For | Marketing pages | Interactive experiences |
Use AOS when :
Use GSAP ScrollTrigger when :
scripts/aos_generator.py - Generate AOS HTML boilerplatescripts/config_builder.py - Build AOS configurationreferences/aos_api.md - Complete AOS API referencereferences/animation_catalog.md - All built-in animations with demosreferences/integration_patterns.md - Framework integration guidesassets/starter_aos/ - Complete AOS starter templateassets/examples/ - Production-ready patternsWeekly Installs
82
Repository
GitHub Stars
11
First Seen
Feb 27, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode82
cursor80
github-copilot80
codex80
amp80
cline80
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
120,000 周安装