scroll-effects

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Skill: scroll-effects

Skill: scroll-effects

Hub hiệu ứng cuộn trang: 64 bản gốc nguyên văn (freefrontend/CodePen, MIT) ở
Rheinmir/uiux-asset
— duyệt gallery, copy nguyên file. Kèm 7 hiệu ứng vanilla tự viết trong
assets/
cho dự án không được kéo lib ngoài.
页面滚动效果中心:64 份逐字保留的原版(freefrontend/CodePen,MIT)位于
Rheinmir/uiux-asset
——可浏览 gallery 并完整复制文件。另附 7 种在
assets/
中自行编写的 vanilla 效果,供不允许引入外部 lib 的项目使用。

WHAT

WHAT

Purpose và context

目的与上下文

  • Purpose: gắn hiệu ứng cuộn trang nhẹ vào trang đích — mặc định copy nguyên file bản GỐC từ
    Rheinmir/uiux-asset
    ; dự án không được kéo lib ngoài thì dùng 7 pattern vanilla trong
    assets/
    .
  • Trigger (when to use):
    • Trang cần hiệu ứng hiện-dần khi cuộn, chữ stagger, highlight dẫn mắt, nav co lại, nút về đầu trang, mục lục bám theo section, hoặc parallax nhẹ.
    • User nói "hiệu ứng scroll", "scroll to top", "scrollspy", "parallax", "reveal khi cuộn".
  • Non-goals: KHÔNG dùng cho: chuyển ảnh điện ảnh nặng GPU (đó là
    blur
    ), trục timeline mốc thời gian (đó là
    timeline
    ), cuộn ngang pin-section kiểu GSAP ScrollTrigger phức tạp (vượt phạm vi skill nhẹ này — nói rõ với user).
  • **目的:**为目标页面添加轻量滚动效果——默认从
    Rheinmir/uiux-asset
    完整复制原版文件;如果项目不允许引入外部 lib,则使用
    assets/
    中的 7 种 vanilla pattern。
  • 触发条件(何时使用):
    • 页面需要滚动渐显、staggered text、引导视线的高亮、收缩式 nav、返回顶部按钮、跟随 section 的目录,或轻量 parallax。
    • 用户说“滚动效果”“scroll to top”“scrollspy”“parallax”“滚动时 reveal”。
  • **非目标:**不适用于:重度 GPU 图像过渡(即
    blur
    )、时间轴(即
    timeline
    ),以及类似 GSAP ScrollTrigger 的复杂横向滚动 pin-section(超出此轻量 skill 的范围——应向用户明确说明)。

Mental model

心智模型

nhu cầu hiệu ứng → gallery 64 bản gốc (mặc định, copy nguyên file) hoặc 7 pattern vanilla (không được kéo lib) → adapt token theo design.md → một IntersectionObserver + một scroll listener rAF → reduced-motion tắt hết → verify playwright
. Hub rẽ sang skill con tương ứng khi mục gallery thuộc skill con.
效果需求 → 64 份原版组成的 gallery(默认,完整复制文件)或 7 种 vanilla pattern(不允许引入 lib)→ 根据 design.md 适配 token → 使用一个 IntersectionObserver + 一个经 rAF 节流的 scroll listener → reduced-motion 下全部关闭 → 使用 playwright 验证
。如果 gallery 中的条目属于某个子 skill,Hub 会转入相应的子 skill。

Input và output contract

输入与输出约定

FieldRequired?Ý nghĩa
Inhiệu ứng cầncómột trong 7 pattern hoặc mục gallery
Inràng buộc dự ánkhôngcó được kéo lib/file ngoài không; có
design.md
không
Outfile hiệu ứng trong dự áncóbản gốc copy nguyên (giữ comment ghi công dòng đầu) hoặc asset vanilla đã adapt
Outbằng chứng verifycóảnh trước/sau cuộn,
.is-in
xuất hiện, không horizontal overflow
字段必填?含义
In所需效果是7 种 pattern 之一或 gallery 条目
In项目约束否是否允许引入外部 lib/file;是否有
design.md
Out项目中的效果文件是完整复制的原版(保留首行署名 comment)或已适配的 vanilla asset
Out验证证据是滚动前后截图、
.is-in
出现、无 horizontal overflow

Rules và capabilities

规则与能力

  • RULE-01 (MUST):
    prefers-reduced-motion: reduce
    → tắt toàn bộ: CSS ép
    .is-in
    hiện ngay không transition, JS bỏ smooth scroll và parallax (đã code sẵn trong assets, đừng xoá nhánh này khi adapt).
  • RULE-02 (MUST): Một
    IntersectionObserver
    dùng chung cho reveal + stagger + highlight + TOC (đã gộp trong
    scroll-effects.js
    ) — đừng tạo 4 observer riêng.
  • RULE-03 (MUST): Scroll listener duy nhất, rAF-throttle — nav + top + parallax đọc chung một
    scrollY
    mỗi frame, không gắn 3 listener
    scroll
    rời.
  • RULE-04 (MUST): Verify bằng
    playwright-verify
    : chụp trước/sau cuộn, assert
    .is-in
    xuất hiện, đo không có horizontal overflow do parallax.
  • RULE-05 (MUST): Khi adapt vào dự án có
    design.md
    : đổi token màu/spacing, giữ nguyên tên
    data-se-*
    (JS bám vào chúng).
  • Capabilities: đọc gallery/repo asset ngoài (mạng) hoặc asset nội bộ; ghi file front-end dự án; chạy trình duyệt headless qua HTTP local.
  • RULE-01(必须):
    prefers-reduced-motion: reduce
    → 关闭所有效果:CSS 强制
    .is-in
    立即显示且不使用 transition,JS 移除 smooth scroll 和 parallax(相关分支已写入 assets,适配时不要删除)。
  • RULE-02(必须):使用一个共享的
    IntersectionObserver
    处理 reveal + stagger + highlight + TOC(已在
    scroll-effects.js
    中合并)——不要创建 4 个独立 observer。
  • RULE-03(必须):只使用一个经 rAF 节流的 scroll listener——nav + top + parallax 每帧共同读取同一个
    scrollY
    ,不要绑定 3 个独立的
    scroll
    listener。
  • RULE-04(必须):使用
    playwright-verify
    验证:截取滚动前后的画面,断言
    .is-in
    出现,并测量 parallax 未造成 horizontal overflow。
  • RULE-05(必须):适配到包含
    design.md
    的项目时:修改颜色/spacing token,同时保留
    data-se-*
    名称(JS 依赖这些属性)。
  • 能力:读取 gallery/外部 repo asset(网络)或内部 asset;写入项目的 front-end 文件;通过本地 HTTP 运行 headless 浏览器。

Failure boundaries

失败边界

  • Yêu cầu là WebGL nặng, timeline mốc, hoặc pin-section GSAP phức tạp → blocked ngoài phạm vi, nói rõ với user và chỉ skill đúng.
  • Không truy cập được gallery/repo ngoài hoặc dự án cấm lib ngoài → dùng 7 pattern vanilla (không phải lỗi).
  • Verify playwright không thấy
    .is-in
    hoặc có horizontal overflow → failed, sửa rồi verify lại.
  • 需求涉及重度 WebGL、时间轴或复杂的 GSAP pin-section → blocked,属于范围外;向用户明确说明,并只使用对应的 skill。
  • 无法访问外部 gallery/repo,或项目禁止引入外部 lib → 使用 7 种 vanilla pattern(这不是错误)。
  • Playwright 验证未发现
    .is-in
    ,或存在 horizontal overflow → failed;修复后重新验证。

HOW

HOW

Main workflow

主工作流

StepTypeInputsActionOutputs/exitFailure/next
W01judgmentyêu cầuKhớp phạm vi (không phải blur/timeline/GSAP pin)hiệu ứng trong phạm vingoài phạm vi → blocked
W02judgmentràng buộc dự ánChọn nguồn: bản gốc gallery (mặc định) hay vanilla
assets/
(B01)
nguồn—
W03effectnguồnBản gốc: mở link chạy → copy nguyên
.html
(+
_assets/
) → giữ comment ghi công → chỉ sửa nội dung/ảnh/màu
file trong dự án—
W04effect
design.md
Adapt token màu/spacing, giữ
data-se-*
, giữ nhánh reduced-motion
file đã adapt—
W05deterministictrang qua HTTP
playwright-verify
: chụp trước/sau cuộn, assert
.is-in
, đo overflow
PASSFAIL → sửa, lặp W05
Chi tiết từng bước (nguồn chân lý cho W01–W05):
步骤类型输入操作输出/退出失败/下一步
W01判断需求判断范围是否匹配(不是 blur/timeline/GSAP pin)范围内的效果超出范围 → blocked
W02判断项目约束选择来源:原版 gallery(默认)或 vanilla
assets/
(B01)
来源—
W03效果来源原版:打开可运行链接 → 完整复制
.html
(以及
_assets/
)→ 保留署名 comment → 只修改内容、图片和颜色
项目中的文件—
W04效果
design.md
适配颜色/spacing token,保留
data-se-*
和 reduced-motion 分支
已适配的文件—
W05确定性通过 HTTP 访问的页面
playwright-verify
:截取滚动前后画面,断言
.is-in
,测量 overflow
PASSFAIL → 修复并重复 W05
以下为每个步骤的详细信息(W01–W05 的依据来源):

Bản gốc — dùng TRƯỚC (copy nguyên file, đừng viết lại)

原版——优先使用(完整复制文件,不要重写)

Code gốc NGUYÊN VĂN của tác giả (CodePen public = MIT) nằm ở repo ngoài
Rheinmir/uiux-asset
— gallery chạy thật: https://rheinmir.github.io/uiux-asset/scroll-effects/ . Quy trình: mở link chạy để xem đúng hiệu ứng → copy nguyên file
.html
(+ thư mục
_assets/
nếu file trỏ tới) vào dự án → giữ comment ghi công dòng đầu → chỉ sửa nội dung/ảnh/màu. Chạy local qua HTTP, không
file://
.
git clone --depth 1 https://github.com/Rheinmir/uiux-asset
nếu cần cả bộ offline.
Hub: duyệt cả 64 mục ở gallery (lọc theo tên/kỹ thuật/tác giả), rồi rẽ sang skill con tương ứng.
assets/
trong skill này chỉ là bản rút gọn vanilla tự viết — dùng khi dự án KHÔNG được kéo lib ngoài; mặc định dùng bản gốc ở trên.
作者的原版代码逐字保留(CodePen public = MIT),位于外部 repo
Rheinmir/uiux-asset
——可通过实际运行的 gallery 访问:https://rheinmir.github.io/uiux-asset/scroll-effects/ 。 流程:打开可运行链接以查看准确效果 → 将
.html
文件完整复制到项目中(如果文件引用了
_assets/
,也复制该目录)→ 保留首行署名 comment → 只修改内容、图片和颜色。通过 HTTP 在本地运行,不要使用
file://
。 如需完整的离线版本,可执行:
git clone --depth 1 https://github.com/Rheinmir/uiux-asset
Hub:浏览 gallery 中的全部 64 个条目(可按名称、技术或作者筛选),然后转入相应的子 skill。
此 skill 中的
assets/
只是自行编写的精简版 vanilla 实现——仅在项目不允许引入外部 lib 时使用;默认使用上述原版。

Assets

Assets

assets/demo.html
(trang demo ráp sẵn cả 7) +
assets/scroll-effects.css
+
assets/scroll-effects.js
— đọc rồi ADAPT (đổi class/token theo
design.md
của dự án nếu có).
assets/demo.html
(预置全部 7 种效果的 demo 页面)+
assets/scroll-effects.css
+
assets/scroll-effects.js
——读取后进行 ADAPT(如果项目存在
design.md
,则修改 class/token)。

Branches

分支

IDKindGuardHành viSkip / failureRejoin
B01conditional_requireddự án KHÔNG được kéo lib/file ngoàidùng 7 pattern vanilla trong
assets/
(mục Reference bên dưới) thay bản gốc
được kéo ngoài → bản gốc galleryW04
B02user_optionalcần cả bộ gốc offline
git clone --depth 1
repo
Rheinmir/uiux-asset
—W03
B03conditional_requiredmục gallery thuộc một skill conrẽ sang skill con tương ứng—kết thúc ở skill con
ID类型条件行为跳过/失败汇合点
B01必需条件分支项目不允许引入外部 lib/file使用
assets/
中的 7 种 vanilla pattern(见下方 Reference)替代原版
允许引入外部内容 → 使用 gallery 原版W04
B02用户可选需要完整的离线原版集合执行
git clone --depth 1
克隆
Rheinmir/uiux-asset
repo
—W03
B03必需条件分支gallery 条目属于某个子 skill转入相应的子 skill—在子 skill 中结束

Validation và stopping

验证与停止条件

Chạy qua HTTP local (không
file://
). PASS khi playwright chụp trước/sau cuộn thấy
.is-in
, không horizontal overflow, và với reduced-motion mọi phần tử hiện ngay. Dừng khi PASS; FAIL thì sửa và verify lại.
通过本地 HTTP 运行(不要使用
file://
)。当 Playwright 截取的滚动前后画面显示
.is-in
、不存在 horizontal overflow,并且 reduced-motion 模式下所有元素立即显示时,判定为 PASS。PASS 后停止;FAIL 则修复并重新验证。

Examples

示例

  • Positive: "thêm scroll to top + scrollspy cho trang docs, không được kéo lib" → B01 dùng
    [data-se-top]
    +
    [data-se-toc]
    từ
    assets/
    , đổi token theo
    design.md
    , giữ
    data-se-*
    → playwright: nút hiện khi
    scrollY > innerHeight
    , link TOC nhận
    .is-active
    .
  • Boundary/failure: "làm section cuộn ngang pin kiểu GSAP" → ngoài phạm vi skill nhẹ này → nói rõ với user, không cố dựng bằng parallax
    data-se-parallax
    .
  • 正向:“为文档页添加 scroll to top + scrollspy,不允许引入 lib” → B01 使用
    assets/
    中的
    [data-se-top]
    +
    [data-se-toc]
    ,根据
    design.md
    修改 token,保留
    data-se-*
    → Playwright:滚动超过
    innerHeight
    后按钮出现,目录链接获得
    .is-active
    。
  • 边界/失败:“实现类似 GSAP 的横向滚动 pin section” → 超出此轻量 skill 的范围 → 向用户明确说明,不要尝试使用 parallax
    data-se-parallax
    强行实现。

Reference — 7 pattern (markup tối thiểu + cơ chế)

参考——7 种 pattern(最小 markup + 实现机制)

1. Reveal on scroll —
[data-se-reveal]

1. Reveal on scroll —
[data-se-reveal]

Phần tử mờ + trượt nhẹ, hiện khi cuộn vào khung nhìn.
html
<div data-se-reveal>Lộ dần khi cuộn tới</div>
IntersectionObserver
gắn
.is-in
→ CSS transition
opacity/translateY
. Tham khảo gallery scroll-effects #9 (Animated Scroll Highlight Annotations) về trường hợp dùng, không dùng code của họ.
元素淡入并轻微位移,在滚动进入视口时显示。
html
<div data-se-reveal>Lộ dần khi cuộn tới</div>
IntersectionObserver
添加
.is-in
→ CSS transition
opacity/translateY
。关于使用场景可参考 gallery scroll-effects #9(Animated Scroll Highlight Annotations),但不要使用其代码。

2. Staggered text —
[data-se-stagger]

2. Staggered text —
[data-se-stagger]

Các dòng chữ hiện nối tiếp nhau.
html
<h2 data-se-stagger>
  <span>Dòng một</span><span>Dòng hai</span><span>Dòng ba</span>
</h2>
JS gán
--i
cho mỗi
span
→ CSS
transition-delay: calc(var(--i) * 90ms)
. Chỉ tách theo phần tử con có sẵn, không tự split text node (giữ DOM đơn giản, tránh lỗi a11y).
各行文字依次出现。
html
<h2 data-se-stagger>
  <span>Dòng một</span><span>Dòng hai</span><span>Dòng ba</span>
</h2>
JS 为每个
span
分配
--i
→ CSS
transition-delay: calc(var(--i) * 90ms)
。仅根据已有的子元素进行拆分,不要自动拆分 text node(保持 DOM 简单,避免 a11y 问题)。

3. Scroll highlight —
[data-se-highlight] > mark

3. Scroll highlight —
[data-se-highlight] > mark

Đánh dấu ý chính, vệt màu quét trái→phải khi đoạn văn vào khung nhìn.
html
<p data-se-highlight>Đọc tới đây <mark>ý chính hiện ra</mark> rồi đọc tiếp.</p>
mark
dùng
background-size: 0% → 100%
transition khi cha có
.is-in
. Dùng
<mark>
ngữ nghĩa thật, không span giả.
突出关键观点;当段落进入视口时,色带从左向右扫过。
html
<p data-se-highlight>Đọc tới đây <mark>ý chính hiện ra</mark> rồi đọc tiếp.</p>
当父元素获得
.is-in
时,
mark
的
background-size
从 0% 过渡到 100%。使用具有真实语义的
<mark>
,不要用
span
代替。

4. Sticky shrink nav —
[data-se-nav]

4. Sticky shrink nav —
[data-se-nav]

Header co gọn khi cuộn xuống, phồng lại khi về đầu.
html
<header data-se-nav class="site-nav">…</header>
Scroll listener (rAF-throttle) toggle
.is-shrunk
khi
scrollY > 24
. Chỉ đổi padding/font-size qua class, không set style inline từng frame.
向下滚动时 header 收缩,回到顶部时重新展开。
html
<header data-se-nav class="site-nav">…</header>
经 rAF 节流的 scroll listener 在
scrollY > 24
时切换
.is-shrunk
。仅通过 class 修改 padding/font-size,不要每帧设置 inline style。

5. Scroll to top —
[data-se-top]

5. Scroll to top —
[data-se-top]

Nút về đầu trang, chỉ hiện sau khi cuộn qua một màn hình.
html
<button data-se-top aria-label="Về đầu trang">↑</button>
Click →
window.scrollTo({ top: 0, behavior: "smooth" })
(trừ khi
prefers-reduced-motion
→
"auto"
). Ngưỡng hiện:
scrollY > innerHeight
.
返回顶部按钮,仅在滚动超过一屏后显示。
html
<button data-se-top aria-label="Về đầu trang">↑</button>
点击 →
window.scrollTo({ top: 0, behavior: "smooth" })
(如果启用
prefers-reduced-motion
,则使用
"auto"
)。显示阈值:
scrollY > innerHeight
。

6. Scrollspy TOC —
[data-se-toc] a[href^="#"]
+
section[id]

6. Scrollspy TOC —
[data-se-toc] a[href^="#"]
+
section[id]

Mục lục sticky, link sáng theo section đang đọc.
html
<nav data-se-toc><a href="#s1">Mục 1</a><a href="#s2">Mục 2</a></nav>
<section id="s1">…</section><section id="s2">…</section>
IntersectionObserver
với
rootMargin: "-40% 0px -55% 0px"
→ link khớp nhận
.is-active
. Tham khảo gallery #19 (Auto-Generated Anchor TOC) về ý tưởng, code tự viết.
sticky 目录,链接根据当前阅读的 section 高亮。
html
<nav data-se-toc><a href="#s1">Mục 1</a><a href="#s2">Mục 2</a></nav>
<section id="s1">…</section><section id="s2">…</section>
IntersectionObserver
设置
rootMargin: "-40% 0px -55% 0px"
→ 匹配项的链接获得
.is-active
。关于设计思路可参考 gallery #19(Auto-Generated Anchor TOC),代码自行实现。

7. Parallax nhẹ —
[data-se-parallax="0.2"]

7. 轻量 Parallax —
[data-se-parallax="0.2"]

Lớp nội dung trôi chậm hơn/nhanh hơn tốc độ cuộn.
html
<div data-se-parallax="0.15">Trôi chậm tạo chiều sâu</div>
rAF loop:
translateY = (elCenter - viewportCenter) * speed
. Giá trị
speed
khuyến nghị
|v| ≤ 0.3
; vượt quá gây say chuyển động. KHÔNG dùng cho chữ nhỏ cần đọc chính xác.
内容层以比滚动速度更慢或更快的速度移动。
html
<div data-se-parallax="0.15">Trôi chậm tạo chiều sâu</div>
rAF loop:
translateY = (elCenter - viewportCenter) * speed
。建议
|v| ≤ 0.3
;超过该值可能引发晕动症。不要用于需要精确阅读的小字号文字。

Origin

来源

  • User chốt "làm đi hỏi nhiều quá" → thay vì bulk-copy 81 tác phẩm, viết BỘ GỐC 7 pattern generic (kỹ thuật chuẩn ngành: IntersectionObserver/scroll listener/rAF — không phải biểu đạt sáng tạo riêng của ai) để downstream tham khảo code mẫu ngay, đúng cách
    blur
    /
    timeline
    đã làm.
  • 用户最终决定“直接做,别问太多” → 因此没有批量复制 81 个作品,而是编写了由 7 个通用 pattern 构成的原版集合(采用行业标准技术:IntersectionObserver/scroll listener/rAF——并非任何人的独创创意表达),供 downstream 立即参考示例代码,做法与现有
    blur
    /
    timeline
    skill 一致。