css-scroll-driven-native
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSkill: css-scroll-driven-native
Skill: css-scroll-driven-native
Hiệu ứng cuộn trang bằng CSS spec công khai — / + — không một dòng JavaScript.
animation-timeline: scroll()view()animation-range使用公开 CSS 规范实现页面滚动效果—— / + ——不写一行 JavaScript。
animation-timeline: scroll()view()animation-rangeWHAT
内容
Purpose và context
目的与上下文
- Purpose: thêm hiệu ứng cuộn (progress bar, reveal-on-view, parallax nhẹ) bằng CSS thuần làm progressive enhancement — trình duyệt chưa hỗ trợ hoặc bật reduce-motion vẫn thấy đủ nội dung tĩnh.
animation-timeline - Trigger (when to use): user nói "css scroll driven animation", "animation-timeline", "scroll animation không js", "css thuần cuộn trang", "scroll-driven CSS", hoặc /css-scroll-driven-native; hoặc muốn thêm "độ mượt" 0-JS phía trên . Chọn theo bảng "Khi nào chọn cái này vs
scroll-effects" (mục Reference).scroll-effects - Non-goals: không phải cơ chế chính khi cần chạy chắc production đa trình duyệt ngay (đó là , JS IntersectionObserver); không viết JS; không cứng số phiên bản trình duyệt.
scroll-effects
- 目的: 使用纯 CSS 添加滚动效果(进度条、进入视窗时显现、轻量级视差),作为渐进式增强——不支持该功能的浏览器或启用 reduce-motion 的用户仍可看到完整的静态内容。
animation-timeline - 触发条件(何时使用): 用户说 、
css scroll driven animation、animation-timeline、scroll animation không js、css thuần cuộn trang或scroll-driven CSS;或者希望在/css-scroll-driven-native基础上增加“零 JS”的流畅效果。根据“何时选择此方案与scroll-effects”对比表(参考部分)进行选择。scroll-effects - 非目标: 当需要立即确保在生产环境中兼容多个浏览器时,不应将其作为主要机制(应使用基于 JS IntersectionObserver 的 );不编写 JS;不在代码中硬编码浏览器版本。
scroll-effects
Mental model
核心模型
timeline (scroll(root) | view()) + animation-range → keyframes; toàn bộ nằm trong @supports → @media not (prefers-reduced-motion: reduce); ngoài hai khối đó = trạng thái tĩnh hiện đủ nội dungtimeline (scroll(root) | view()) + animation-range → keyframes@supports@media not (prefers-reduced-motion: reduce)Input và output contract
输入与输出约定
| Field | Required? | Ý nghĩa | |
|---|---|---|---|
| In | cơ chế cần (progress / reveal / parallax) | có | chọn 1–3 trong 3 cơ chế |
| In | | không | có thì đổi token màu/spacing theo nó |
| Out | CSS (+ markup tối thiểu) adapt từ | có | mọi animation trong |
| Out | bằng chứng verify | có | ảnh 0%/50%/100% scroll + ảnh reduce-motion qua |
| 字段 | 是否必填 | 含义 | |
|---|---|---|---|
| 输入 | 所需机制(progress / reveal / parallax) | 是 | 从 3 种机制中选择 1–3 种 |
| 输入 | 项目的 | 否 | 如存在,则根据它调整颜色和 spacing token |
| 输出 | 基于 | 是 | 所有 animation 均置于 |
| 输出 | 验证证据 | 是 | 通过 |
Rules và capabilities
规则与能力
Rules (BẮT BUỘC):
- RULE-01 (MUST): Luôn có fallback : mọi animation nằm trong
@supportshoặc@supports (animation-timeline: scroll()). Bên NGOÀI khối@supports (animation-timeline: view())là trạng thái TĨNH mặc định — phần tử hiện đủ nội dung, không animation, KHÔNG BAO GIỜ ẩn/opacity:0 làm mặc định. Nếu viết@supportscho hiệu ứng reveal, giá trị đó CHỈ được đặt bên trongopacity:0, không phải ở rule gốc.@supports - RULE-02 (MUST): : bọc animation trong
prefers-reduced-motion(lồng bên trong@media not (prefers-reduced-motion: reduce), xem@supports). Người dùng bật reduce-motion → mọi phần tử về trạng thái tĩnh giống hệt trình duyệt không hỗ trợ.demo.css - RULE-03 (MUST): KHÔNG cứng số phiên bản vào code hay comment — kiểm tra caniuse.com/css-scroll-driven-animations mỗi lần dùng thật (bảng hỗ trợ ở mục Reference).
- RULE-04 (MUST): vẫn phải khai (
animation-durationhoặc giá trị bất kỳ >0) dù thời lượng thật do timeline điều khiển — một số engine yêu cầu giá trị này để kích hoạt animation.1ms - RULE-05 (MUST): Verify bằng trên trình duyệt Chromium (CDP mặc định hỗ trợ scroll-driven animations): chụp ảnh tại 0%/50%/100% scroll, assert progress bar/scaleX và card opacity đổi theo vị trí cuộn; đồng thời chụp thêm với
playwright-verifygiả lập (Playwrightprefers-reduced-motion: reduce) để assert KHÔNG animation nhưng nội dung vẫn hiện đủ.emulateMedia - Capabilities: đọc asset skill + ; ghi CSS/HTML vào dự án đích; chạy trình duyệt Chromium headless có giả lập media.
design.md
规则(必须遵守):
- RULE-01(必须):始终提供 fallback:所有 animation 均放在
@supports或@supports (animation-timeline: scroll())中。@supports (animation-timeline: view())代码块之外默认为静态状态——元素完整显示内容,不包含 animation,绝不能默认隐藏元素或设置@supports。如果为 reveal 效果编写opacity:0,该值只能放在opacity:0内部,不能放在基础规则中。@supports - RULE-02(必须)::将 animation 包裹在
prefers-reduced-motion中(嵌套在@media not (prefers-reduced-motion: reduce)内部,参见@supports)。当用户启用 reduce-motion 时,所有元素都会回到与不支持该功能的浏览器完全相同的静态状态。demo.css - RULE-03(必须):不得在代码或注释中硬编码浏览器版本——每次实际使用时都应检查 caniuse.com/css-scroll-driven-animations(支持情况表见参考部分)。
- RULE-04(必须):即使实际时长由 timeline 控制,仍必须声明 (
animation-duration或任意大于 0 的值)——部分引擎需要该值才能激活 animation。1ms - RULE-05(必须):使用 在 Chromium 浏览器中验证(CDP 默认支持 scroll-driven animations):分别截取 0%/50%/100% 滚动位置的图片,断言 progress bar/scaleX 和 card opacity 会随滚动位置变化;同时使用模拟的
playwright-verify再截取图片(Playwrightprefers-reduced-motion: reduce),断言此时没有 animation,但内容仍完整显示。emulateMedia - 能力:读取 skill asset + ;向目标项目写入 CSS/HTML;运行支持媒体模拟的 headless Chromium。
design.md
Failure boundaries
失败边界
- Yêu cầu "phải chạy chắc trên mọi trình duyệt ngay" → clarify/chuyển làm nền, skill này chỉ override.
scroll-effects - Nội dung bị ẩn khi sai hoặc reduce-motion bật → failed (vi phạm RULE-01/02), sửa trước khi giao.
@supports - Ảnh 0%/50%/100% giống hệt nhau trên Chromium → failed (animation không kích hoạt, thường thiếu ).
animation-duration
- 要求“必须立即在所有浏览器中稳定运行” → clarify/切换到 作为基础,此 skill 仅执行覆盖。
scroll-effects - 当 编写错误或启用 reduce-motion 时内容被隐藏 → 失败(违反 RULE-01/02),必须先修复再交付。
@supports - Chromium 中 0%/50%/100% 的图片完全相同 → 失败(animation 未激活,通常是因为缺少 )。
animation-duration
HOW
方法
Main workflow
主要工作流
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|---|---|---|---|---|
| W01 | judgment | yêu cầu + đích trình duyệt | Chọn skill này hay | quyết định | cần chắc đa trình duyệt → B01 |
| W02 | deterministic | | Đọc | snippet | — |
| W03 | effect | snippet, | ADAPT token màu/spacing; đặt animation trong | CSS trong dự án | — |
| W04 | deterministic | trang đã gắn | Verify RULE-05: chụp 0/50/100% + | ảnh + assert | assert đỏ → sửa, lặp W04 |
| 步骤 | 类型 | 输入 | 操作 | 输出/退出条件 | 失败/下一步 |
|---|---|---|---|---|---|
| W01 | 判断 | 需求 + 目标浏览器 | 根据对比表选择此 skill 或 | 决策 | 需要确保多浏览器兼容 → B01 |
| W02 | 确定性 | | 读取 | snippet | — |
| W03 | 效果实现 | snippet、 | ADAPT 颜色/spacing token;将 animation 放入 | 项目中的 CSS | — |
| W04 | 确定性 | 已集成的页面 | 验证 RULE-05:截取 0/50/100% 图片 + | 图片 + assert | assert 失败 → 修复并重复 W04 |
Branches
分支
| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|---|---|---|---|---|
| B01 | user_optional | cần chạy chắc đa trình duyệt nhưng vẫn muốn 0-JS mượt hơn | kết hợp: | chỉ cần Chromium → skip | W02 |
| ID | 类型 | 条件 | 行为 | 跳过/失败 | 汇合点 |
|---|---|---|---|---|---|
| B01 | user_optional | 需要确保多浏览器稳定运行,但仍希望获得更流畅的 0-JS 效果 | 组合使用:以 | 只需要 Chromium → 跳过 | W02 |
Validation và stopping
验证与停止条件
Assert tất định ở W04 (scaleX/opacity đổi theo vị trí cuộn; reduce-motion không animation, nội dung đủ). Cần mắt: độ mượt/hợp design. Dừng khi hai loại ảnh đều đạt; 2 vòng vẫn đỏ → báo user kèm ảnh.
在 W04 执行确定性断言(scaleX/opacity 随滚动位置变化;reduce-motion 下没有 animation 且内容完整)。还需要人工检查流畅度及设计一致性。当两类图片均通过时停止;如果 2 轮后仍然失败,则向用户报告并附上图片。
Examples
示例
- Positive: "thêm progress bar đọc bài bằng css thuần" → với
.csdn-progresstronganimation-timeline: scroll(root)+ reduce-motion guard → ảnh 0%/50%/100% cho scaleX 0 → ~0.5 → 1.@supports - Boundary/failure: reveal card đặt ở rule gốc → trên Firefox chưa hỗ trợ card biến mất → vi phạm RULE-01, chuyển
opacity:0vào trongopacity:0rồi verify lại với reduce-motion.@supports
- 正向示例: “使用纯 CSS 为文章添加阅读进度条” → 使用带 的
animation-timeline: scroll(root),置于.csdn-progress+ reduce-motion guard 中 → 提供 0%/50%/100% 的图片,展示 scaleX 从 0 → 约 0.5 → 1。@supports - 边界/失败示例: 在基础规则中为 reveal card 设置 → 在尚不支持该功能的 Firefox 上 card 会消失 → 违反 RULE-01,应将
opacity:0移入opacity:0内,然后使用 reduce-motion 重新验证。@supports
Reference — Khi nào chọn cái này vs scroll-effects
scroll-effects参考——何时选择此方案与 scroll-effects
scroll-effects | | |
|---|---|---|
| JS | 0 dòng | IntersectionObserver + rAF |
| Hỗ trợ trình duyệt | Chrome/Edge tốt; Firefox/Safari đang rollout, có thể chưa bật mặc định | Mọi trình duyệt hiện đại |
| Khi dùng | Progressive enhancement — thêm "độ mượt" cho trình duyệt đã hỗ trợ, KHÔNG phải cơ chế chính nếu cần chạy chắc production đa trình duyệt ngay | Cơ chế chính khi cần chạy chắc ngay, không đợi rollout |
Khuyến nghị: dùng skill này bên trong , fallback tĩnh (không animation, không ẩn nội dung) — hoặc kết hợp cả hai: làm nền, skill này override khi trình duyệt hỗ trợ.
@supports (animation-timeline: scroll())scroll-effects⚠️ Kiểm tra hỗ trợ thật trước khi dùng production tại caniuse.com/css-scroll-driven-animations — đừng tin số liệu cứng ghi trong tài liệu này, API đang rollout nhanh và bảng hỗ trợ có thể đã đổi.
Bảng hỗ trợ trình duyệt hiện tại (ghi tại thời điểm viết skill, 2026-09 — có thể đã đổi, luôn tự kiểm tra):
| Trình duyệt | | |
|---|---|---|
| Chrome / Edge | Có | Có |
| Firefox | Behind flag / đang rollout | Behind flag / đang rollout |
| Safari | Đang rollout, chưa ổn định | Đang rollout, chưa ổn định |
| | |
|---|---|---|
| JS | 0 行 | IntersectionObserver + rAF |
| 浏览器支持 | Chrome/Edge 支持良好;Firefox/Safari 正在 rollout,可能尚未默认启用 | 所有现代浏览器 |
| 使用场景 | 渐进式增强——为已支持的浏览器增加“流畅度”;如果需要立即确保生产环境中的多浏览器兼容,则不应将其作为主要机制 | 需要立即确保稳定运行、无需等待 rollout 时使用的主要机制 |
建议:在 内使用此 skill,并提供静态 fallback(无 animation、不隐藏内容);也可以组合使用两者:以 为基础,在浏览器支持时由此 skill 覆盖。
@supports (animation-timeline: scroll())scroll-effects⚠️ 投入生产环境前务必检查实际支持情况:访问 caniuse.com/css-scroll-driven-animations——不要相信本文档中记录的固定数据,该 API 正在快速 rollout,支持情况可能已经发生变化。
当前浏览器支持表(记录于 skill 编写时,2026-09——可能已经发生变化,请始终自行检查):
| 浏览器 | | |
|---|---|---|
| Chrome / Edge | 支持 | 支持 |
| Firefox | Behind flag / 正在 rollout | Behind flag / 正在 rollout |
| Safari | 正在 rollout,尚未稳定 | 正在 rollout,尚未稳定 |
Reference — Assets
参考——Assets
assets/demo.htmlassets/demo.cssdesign.mdassets/demo.htmlassets/demo.cssdesign.mdReference — 3 cơ chế (markup tối thiểu + cơ chế)
参考——3 种机制(最少 markup + 机制)
1. Progress bar theo cuộn trang
1. 随页面滚动的进度条
Thanh cố định trên cùng, dài theo % đã cuộn hết trang.
html
<div class="csdn-progress"></div>css
.csdn-progress {
animation-name: progress-scale;
animation-duration: 1ms; /* giá trị bất kỳ để kích hoạt engine — thời lượng thật do timeline điều khiển */
animation-timeline: scroll(root);
animation-fill-mode: both;
}
@keyframes progress-scale {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}scroll(root)scrollscrollY / scrollHeight固定在页面顶部,宽度对应页面已滚动的百分比。
html
<div class="csdn-progress"></div>css
.csdn-progress {
animation-name: progress-scale;
animation-duration: 1ms; /* giá trị bất kỳ để kích hoạt engine — thời lượng thật do timeline điều khiển */
animation-timeline: scroll(root);
animation-fill-mode: both;
}
@keyframes progress-scale {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}scroll(root)scrollscrollY / scrollHeight2. Reveal-on-view khi phần tử vào khung nhìn
2. 元素进入视窗时执行 Reveal-on-view
html
<article class="csdn-card">…</article>css
.csdn-card {
animation-name: reveal-in;
animation-timeline: view();
animation-range: entry 0% cover 40%;
animation-fill-mode: both;
}view()animation-range: entry 0% cover 40%entry 0%html
<article class="csdn-card">…</article>css
.csdn-card {
animation-name: reveal-in;
animation-timeline: view();
animation-range: entry 0% cover 40%;
animation-fill-mode: both;
}view()animation-range: entry 0% cover 40%entry 0%3. Parallax nhẹ dùng view()
view()3. 使用 view()
实现轻量级视差
view()Nền và nội dung dùng khác nhau trên cùng một timeline → tạo cảm giác lớp trôi khác tốc độ, không cần tính toán thủ công.
animation-rangeview()scrollYcss
.parallax-bg { animation-timeline: view(); animation-range: cover 0% cover 100%; } /* trôi chậm, suốt cả quãng */
.parallax-content { animation-timeline: view(); animation-range: entry 0% cover 35%; } /* chạy nhanh, chỉ đoạn đầu */Xem mục 3 để có keyframes đầy đủ.
assets/demo.css背景和内容在同一个 timeline 上使用不同的 → 营造不同速度的层间漂移效果,无需手动计算 。
view()animation-rangescrollYcss
.parallax-bg { animation-timeline: view(); animation-range: cover 0% cover 100%; } /* trôi chậm, suốt cả quãng */
.parallax-content { animation-timeline: view(); animation-range: entry 0% cover 35%; } /* chạy nhanh, chỉ đoạn đầu */有关完整的 keyframes,请查看 的第 3 节。
assets/demo.cssOrigin
来源
- Bổ sung cho (JS-based, chạy mọi trình duyệt) một lựa chọn 0-JS cho trình duyệt đã hỗ trợ — hai skill KHÔNG thay thế nhau, dùng theo bảng "Khi nào chọn cái này" ở trên.
skills/scroll-effects
- 为 (基于 JS,兼容所有浏览器)补充一个面向受支持浏览器的 0-JS 选项——两个 skill 不可相互替代,应根据上文的“何时选择此方案”对比表使用。
skills/scroll-effects