design-frontend | 前端设计通用原则专项
本技能是 design-workflow 主技能抽离出的专项方法论,专治"把数字产品/网页/App 界面做得不像 AI 默认模板、信息结构诚实、动效克制有意图"。 来源署名见
../references/来源署名/anthropics-frontend-design.md(Anthropic 前端设计通用原则文档 · 公开通用原则)。
一、结构装置即信息(编号/眉标/分隔线/标签须承载真相)
- 核心:编号、眉标(eyebrow)、分隔线、标签等"结构装置"应编码内容真相,而非装饰。它们要么说明内容本身的秩序,要么一无是处。
- 质疑装饰性编号:
01 / 02 / 03仅当内容真是序列(真实流程、带序时间轴、步骤必须按序读)时才用;若只是并列清单,编号是假秩序 → 删掉,改用其他区分手段(间距/分组/图标)。 - 自检:每条编号/分隔线被删后,读者是否丢失了某条关于内容本身的信息?若否,它就是装饰,删。
二、反模板校准(避免 AI 默认观感)
下面是需警惕的默认观感——它们本身合法,但当 brief 未指定某一轴时,别把自由浪费在这些"无意识默认"上。brief 原话优先(它明确要求时照做)。
- 默认观感 A:暖米白底(近
#F4F1EA)+ 高对比衬线 Display + 陶土橙点缀。 - 默认观感 B:近黑底 + 单一荧光绿 / 朱红点缀。
- 默认观感 C:报纸式细线规则 + 零圆角 + 密集多栏。
校准方法:定稿前自问"换一个相似 brief 我是否也会落到这?"——若答案是"会",且 brief 没要求,就换一个为该 brief 定制的方向。
三、复杂度匹配愿景
- 极简方向 → 功力在间距 / 字 / 细节的精度,不在加东西;极繁方向 → 需层次、纹理、动效、精雕细节撑住,否则显空。
- 优雅 = 把所选方向执行到位,而非堆效果。与「信息优先级·主信息唯一」「把大胆用在一处」同源:signature 元素是唯一记忆点,其余安静、克制。
- 自检:删掉一个装饰后整体是否成立甚至更好?若成立,说明它本不该在。
四、文案即物料(UX 写作)
- 文案是设计材料,非装饰:文字出现在设计里,只为让人更易理解、更易使用。带来与间距/颜色同等的自觉性。
- 从用户侧写:用用户能掌控/辨识的词命名("管理通知"而非"webhook 配置");描述它做什么,而非推销它。
- 主动语态 + 同名一贯:按钮"发布"→ 提示"已发布",同一动作全程同名,词汇是导航的路标。
- 失败/空状态是引导时刻,非情绪:说清错在哪、怎么修(错误不道歉、不模糊);空屏是行动邀请,不是空白。
- 与「文字」模块区分:本技能管"说什么/怎么写"(内容),主技能
02-感知物料/文字.md管"怎么排/什么字体"(形式)。
五、动效编排时刻
- 一个编排好的"主角时刻" > 零散微动画:开场序列 / 滚动揭示 / 一处精心设计的入场,比到处撒hover/脉冲更抓人。先问"这段动效服务于哪个 subject 的瞬间",再决定做不做。
- 额外动画 = AI 生成感信号:动效过多、过碎会让成品显"AI slop"。同屏同时运动元素默认 ≤3–5 个——克制是高级感的来源;破格触发器:单焦点 / signature 记忆点元素允许 1 个突破预算(其余让位、错峰)。
- 与"主观输出"校准:若动效让观者意识到"这里在动"而非"这里在讲",就是过了。尊重
prefers-reduced-motion仍是硬底线。
六、动效语义与具体手法
仅抽通用设计原理;具体动效编辑器类工作流不纳入。
- 动效传达语义,而非装饰:每个动效应能一句话说清"它传达了什么意图 / 状态 / 情绪"(如打字=启动感、扫光=强调、进度=等待)。动效是"信息层"不是"烟花层"。
- "语义"≠"功能语义",情绪 / 玩味意图也算可命名载荷:随光标漂浮、随滚动轻轻晃、明明不传达具体信息但就是"轻松好玩"的动效,其意图即"松弛 / 有趣 / 玩味",合法。真正要砍的只有"既无语义、又无情绪、只是因为默认'东西该动'才堆上去"的 AI-slop 式动效。一句话判别:能说出"它让观者感到什么 / 想到什么"→ 保留;说不出任何感受也无功能用途 → 砍。
- 文本动效:文字作为一等动效对象(Kinetic Typography):文字不只是静态信息,可独立运动——逐字浮现 / 解密、数字滚动计数、焦点跳跃、字符位移。用于强调关键信息或建立节奏,而非让所有文字都动;与「同屏运动元素默认 ≤3–5」预算同守(单焦点破格除外)。
- 沿路径运动:元素可沿手绘 / 吸附路径(直线 · 圆 · 椭圆)运动,制造"视线被引导沿某轨迹走"的叙事感。
- 统一运动动词表:用一套稳定动词(进入 / 强调 / 退出 / 路径 / 序列)描述所有动效,跨元素一致、便于组合与交接。
- 动效可组合叠加:进 / 出场、强调、注意等预设可叠加至任意层(文本 / 图 / 视频)快速组合含义;但叠加仍受「同屏默认 ≤3–5 元素」预算约束(单焦点破格除外)。
七、动效通用性能与降级(与主技能动画模块配套)
- 只动
transform/opacity(GPU 友好),避免动width/height/top(触发重排);目标 60fps,低端机保底 30fps。 - 无障碍降级(必做):尊重
prefers-reduced-motion——动效降为瞬时淡入/直接切换,不位移、不闪烁、不循环。关键信息(报错、状态)不能只靠动效传达。
八、交互工程对错清单(功能型产品 UI / APP 专用)
适用边界(重要):本节仅用于功能性产品界面 / APP 交互组件——toast、表单、下拉、按钮、拖拽、键盘操作等以「顺手、响应快、不烦人」为核心价值的界面(写程序 / 做 APP 的场景)。 不适用:以设计感 / 氛围 / 叙事 / 传播为目标的网页、海报、品牌页、叙事长页——那种场景回到主技能
动画.md(数量预算 + 破格)与references/惊艳手法库.md,按「饱满有意图」的标准走,不套用本节清单。 来源:吸收自 emilkowalski/skills(MIT),来源署名见references/来源署名/emilkowalski-skills.md。
对错清单(AI 最容易错的点)
| ❌ 错 | ✅ 对 | 为什么 |
|---|---|---|
transition: all |
transition: transform 200ms ease-out |
all 触发布局重算,不可预期 |
从 scale(0) 进场 |
scale(0.95) + opacity:0 起步 |
物体不从虚无中出现 |
入场用 ease-in |
ease-out 或自定义曲线 |
ease-in 起步慢 = 界面迟钝 |
popover transform-origin: center |
锚定触发器 var(--transform-origin) |
从触发点"长出来";模态框例外(居中) |
Framer 简写 x/y/scale |
transform:"translateX()" |
简写不走硬件加速 |
| 键盘触发加动画 | 完全不加 | 高频操作,动画=延迟感 |
| hover 无媒体查询 | @media (hover:hover) and (pointer:fine) |
触摸屏 tap 会误触发 hover |
| 高频元素用 keyframes | 用 CSS transitions | 可中断、可重定向 |
| Enter/Exit 同速 | 退出比进入快 | 退出是系统响应,必须快 |
| blur > 20px | ≤ 20px | Safari 高模糊昂贵 |
| stagger 间隔过长 | 30–80ms | 太长显拖沓 |
| spring bounce > 0.3 | 0.1–0.3,多数 UI 避免 | 弹太狠 = 玩具感 |
参数表("对"长什么样)
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* UI 交互默认 */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* 屏上元素 A→B 移动 */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS 抽屉 */
- 时长表(UI 硬上限 300ms):按钮按压 100–160ms · tooltip 125–200ms · dropdown 150–250ms · modal/drawer 200–500ms · 营销/展示动画可更长
- 按钮按压:
:active scale(0.97)+transform 160ms ease-out - spring:Apple 风格
{type:"spring", duration:0.5, bounce:0.2};传统{mass:1, stiffness:100, damping:10} - 拖拽 dismiss:速度阈值
velocity > 0.11
评审输出格式(Review 三列)
动效评审一律用 Markdown 三列表 Before | After | Why(禁止"Before:/After:"分行格式):
| Before | After | Why |
|---|---|---|
transition: all 300ms |
transition: transform 200ms ease-out |
只动需要动的属性 |
transform: scale(0) |
transform: scale(0.95); opacity:0 |
现实物体不从虚无出现 |
ease-in on dropdown |
ease-out 自定义曲线 |
ease-in 显迟钝 |
决策顺序与目的门控(动效该不该做、为什么做)
对错清单管"做对了没有",本段管"该不该做、为谁做"——顺序在前,参数在后。
- 顺序即纪律:先过"该不该动"的频率门控(见上「频率–动效决策原则」),再命名"目的",最后才选曲线/时长参数。不要没定目的就先挑缓动。
- 目的命名门控:每个动效必须能用下列之一命名;命名不出 → 不做("看起来酷"在高频元素上是停手的理由,不是做的理由):
- 反馈(确认界面听到了用户)· 空间一致性(显示某物从哪来/去哪)· 状态指示(让状态变化可读)· 防止突兀变化(bridging 否则会瞬移的内容)· 解释(演示原理,仅营销/引导)· 愉悦(仅限罕见/首次层级,如引导、成功、庆祝)。
- 功能优先于风格:用户正在读或操作的数据不应为"风格"而移动;装饰性鼠标跟随动效属于营销页,不属于数据密集型界面里的图表。
- 键盘触发的动作直接判负:命令面板开关等每天开合上百次的操作,正确做法是零动画(主流命令面板无开合动画即为此理)。
自检清单(交付前)
- 每个编号 / 眉标 / 分隔线被删后是否丢失了关于内容的真相?(结构装置即信息)
- 是否落入了某个 AI 默认观感(暖米白+衬线+陶土橙 / 近黑+荧光绿 / 报纸细线密栏)而无 brief 支撑?
- 复杂度是否匹配愿景(极简不加、极繁有层次)?
- 文案是否从用户侧写、主动语态、同名一贯、空状态是引导而非情绪?
- 动效是否每个都可命名意图(语义或情绪)?无意图的 AI-slop 动效是否已砍?
- 是否只动
transform/opacity、尊重prefers-reduced-motion? - 是否有一个精心编排的"主角时刻"而非零散微动画?
- 【功能型产品 UI / APP】是否过了「八、交互工程对错清单」(transition:all / scale(0) / ease-in 入场 / 键盘操作不动效 / hover 门控 / 时长 ≤300ms)?
- 【有目标稿 / 设计稿 / 参考稿时】是否过了双评审闸门:盲 scout 只拿到并排比对图(不给意图、spec、ID、参数、builder 辩护)→ 放行;且每个关键特征单独过闸(logo 轮廓 / 主视觉主体 / 标题层级 / 品牌色落点 / signature 元素)?关键特征失败不得被整体分掩盖。
- 改稿是否只改挑战者、冠军不动、失败事务性回滚?连续三次无实质改进是否已换路子而非继续磨?(机制见主技能
05-主观输出/感觉.md「补充 · 双评审闸门」)
边界与维护
- 本技能只管"前端/数字产品的通用设计原则",具体排版/配色/留白等落到主技能
design-workflow的对应层。 - 动效的具体时序/缓动/时长数值见主技能
02-感知物料/动画.md;本技能聚焦"意图与克制"层面。 - 若要在通用设计流程里用:由主技能
design-workflow在载体=UI/数字产品/网页时路由到本技能。
补充 · 动效审计与组件选型纪律
来源:吸收自 emilkowalski/skills 的
improve-animations(存量动效审计工作流)与pick-ui-library(组件选型纪律),已通用化、去具体库名,未引入其私有 IP。与既有「交互工程对错清单」「频率–动效决策原则」构成「该不该做 → 做对没有 → 存量体检」完整链路。
一、存量动效审计工作流(对已有前端/UI 代码库做"动效体检")
当任务不是"从零做动效"而是"这个 App 动效很烂 / 帮我审计一遍"时,按以下流程产出可执行的修复计划(只读分析、不改源码):
- 摸排(Recon):先摸清技术栈(框架 / 动效库 / 组件库)、动效驻留处(全局 token、Tailwind 配置、keyframes、
transition/animate用法、手势 handler)、既有约定(缓动 token、时长标尺——计划须沿用而非另起一套)、产品性格(玩具感消费 App vs 严谨仪表盘)、频率图(哪些元素每天被触发 100+ 次 vs 偶尔 vs 罕见,驱动严重性)。 - 八维审计:目的与频率 / 缓动与时长 / 物理感与锚点 / 可中断性 / 性能 / 无障碍 / 一致性(token) / 缺失机会。大仓库可拆成并行子任务按维度查。
- 分级定级:按「影响 ÷ 成本」排序;HIGH=破坏手感(UI 错缓动、键盘/高频动作加了动画、掉帧、scale(0));MEDIUM=明显不对(错锚点、动态 UI 不可中断、缺 reduced-motion);LOW=打磨(stagger、blur 遮罩交叉淡入、token 收敛)。
- 产出自包含计划:每条发现写成一个计划,精确到 文件路径 + 当前代码摘录 + 目标值(具体 cubic-bezier / 时长 / spring 配置,源自既有约定,不近似编造)+ 验证方式(慢放 / 逐帧 / 真机手势)。不自动改源码、先让人选要修哪几条。
- 别重复已有决策:若代码/注释已记录刻意的动效权衡,尊重它、标注而非举报。
二、组件选型纪律(先选型,别手写废弃组件)
当任务需要的其实是一个"组件"而非"一段动画"(toast / drawer / command menu / dropdown / 数字滚动 / 虚拟化长列表 / 状态管理 / 条件 className 等):
- 先按任务语义归类,再决定用什么;用户说的库名未必等于真实任务类型("我要个下拉"本质是 UI 原语任务)。
- 优先成熟库而非手写:手写
<div>dropdown 极易漏掉焦点管理 / 无障碍 / 关闭逻辑;数字滚动重渲染文本不如专用组件处理数位过渡。 - 先看项目已装什么:已用某库就沿用,别引入竞争依赖制造改动噪音。
- 简单 hover/fade 用原生 CSS,不要为此引一个动效库。
- 具体库随生态演进,按需查当前推荐——本技能不固化具体库名(避免过时)。
三、组件实现基底:shadcn/ui(接入方式)
当载体 = React/Next.js + Tailwind 的 Web 应用,需要做按钮 / 弹窗 / 表单 / 下拉等生产级交互组件时,用 shadcn/ui 作组件源,避免每次从零造轮子。它是「组件选型纪律」的具体落地推荐(非唯一解;项目已用其他体系则沿用之,不强行替换)。
- 是什么:可复制粘贴的组件源码(非 npm 黑盒依赖)。用 CLI 把组件源拉进你项目的
components/ui/,代码归你所有、可改可提交,不锁定版本、不随上游发版突变。 - 接入步骤:
- 前置:已初始化 React/Next.js 项目 + 已配置 Tailwind CSS(shadcn 不替你装框架与 Tailwind)。
- 初始化:
npx shadcn@latest init(按提示设--base-color、路径别名等;--base-color只是初始化配置项,不在此强行规定审美方向)。 - 添加组件:
npx shadcn@latest add button dialog sheet card input select tabs(按需列组件名,逐个把源码拉到本地components/ui/)。 - 使用:直接
import { Button } from "@/components/ui/button"调用;要改就改本地源码,改动随项目走。
- 底层:Radix UI(键盘 / 焦点 / ARIA 无障碍原语)+ Tailwind CSS 工具类。
- 与「零运行时依赖」原则一致:拉一次即落本地文件,构建期无 CDN 拉取、无外部运行时(呼应 hogwarts3d 召回坑:CDN 拉 Three.js 致用户端"点击没反应")。
- 边界:它是组件源,不替代五层设计方法与本技能的设计原则;审美、结构、动效克制仍由 design-workflow 定。纯 HTML / vanilla JS 项目用不了(需 React 生态)。
npx shadcn init会在globals.css生成一套默认 neutral 色板(取决于所选--base-color)——那是占位脚手架,请用工位流02-感知物料层产出的色板覆盖之;本技能不规定任何色值。 - 演进提示:CLI 命令与
--base-color取值随 shadcn 版本变化,以ui.shadcn.com/docs当前文档为准,本段不固化具体命令参数。
补充 · 字体实现基底:Fontsource(自托管字体接入方式)
当载体 = 网页 / Web 应用,需要把字体自托管进项目(而非运行期从 Google Fonts CDN 拉)时,用 Fontsource 作字体交付源。它与 shadcn/ui 同源:都是「零外部运行时」原则的落地——呼应 hogwarts3d 召回坑。
- 是什么:把开源字体打成独立 npm 包;安装后字体文件随构建产物落本地,运行期无外部字体请求(对比 Google Fonts CDN:省一次 DNS+TCP、版本锁定、隐私、可离线)。
- 接入步骤:
- 装包:
npm install @fontsource/<字体名>(静态字重)或npm install @fontsource-variable/<字体名>(可变字体,推荐)。 - 引入:入口 CSS
@import '@fontsource/<字体名>/<字重>.css';(如/400.css、/600.css),或在 JSimport '@fontsource/inter/400.css'。 - 使用:CSS 里
font-family: '<字体名>';,权重按引入的 css 走。 - 构建:Vite/Next/webpack 等打包器把 woff2 一并产出,无需手动搬文件。
- 装包:
- 与「零运行时依赖」原则一致:字体文件进本地构建,运行期不连 Google Fonts CDN(呼应 hogwarts3d 召回坑)。
- 边界:它是字体交付源,不替你选字;用哪款字由工位流
02-感知物料层定(字体属感知物料,见modules/02-感知物料/文字.md)。Fontsource 只负责把 workflow 选定的字自托管进来。具体包名/引入路径随版本演进,以 fontsource.org/docs 当前文档为准。
补充 · 组件过渡选型参考(CSS 落地 · 仅组件级 CSS 过渡载体时调用)
触发边界:本段仅在「载体 = 网页 / Web 应用,需要做组件级 CSS 过渡(下拉 / 模态 / 成功 / 错误抖动 / 骨架屏 / Tab 等常见交互的进出场)」时调用。它不替代第八节 emilkowalski 的「该不该动 / 做对没有」——那两条是通用纪律,本段是"选哪个过渡 + 用什么节奏 token"的选型层。可与 GSAP 段并列:本段管"选哪个过渡 / 词汇与节奏 token",GSAP 段管"用 JS 库怎么写";两者皆须先过第八节。 来源:吸收自 Jakubantalik/transitions.dev(开源 CSS 过渡库 + agent skill),已去名化为通用选型纪律与词汇表;具体 CSS 片段随源站演进,以官方当前版本为准,本段不粘贴源码。
一、匹配纪律:先元素 → 再动词 → 平局按开销
- 先匹配可见 UI 元素,再匹配动词:同一"打开"动词因元素不同落不同过渡——表面从触发器生长 →
menu dropdown(有锚点);表面居中、无锚点 →modal(居中);表面滑入页面某区 →panel reveal。 - 平局按开销取舍(默认选更轻的):
card resize>panel reveal;dropdown>modal;success check> 整模态庆祝。除非设计明确要求更重的表面,否则默认低开销。 - 无清晰匹配 → 回退让人选,不猜测塞一个过渡。
- 组合而非堆砌:
success check是纯动画;若还需从 spinner 换到对勾,须搭配icon swap组合,而非把 check 当万能庆祝。
二、组件过渡词汇表(命名即沟通)
把常见交互的动效命名规范化——命名本身就是设计词汇,避免每次"即兴发挥"导致各组件节奏散掉。下面复用率最高的核心词汇(按交互意图分组,非穷举):
| 意图 | 命名过渡 | 何时用 |
|---|---|---|
| 容器尺寸变化 | card resize |
元素宽/高随布局态变化 |
| 数字更新 | number pop-in |
数值变化时逐位带模糊滑入 |
| 触发点上方小徽标 | notification badge |
触发器上方悬浮小圆点弹出 |
| 文本原地替换 | text states swap |
文本原地内容变更(带模糊上下移) |
| 锚定触发器生长 | menu dropdown |
原点感知的下拉,从触发器长出 |
| 居中弹出层 | modal |
居中、无锚点的对话框(缩放进出) |
| 滑入页面某区 | panel reveal |
侧栏/抽屉滑入某区域(带交叉模糊) |
| 双屏切换 | page side-by-side |
列表↔详情 / 步骤1↔步骤2 |
| 同槽位两图标 | icon swap |
同一位置两个图标交叉淡入缩放 |
| 成功/完成时刻 | success check |
对勾/支付完成/文件上传(淡+旋+Y浮+描边绘制) |
| 横向堆叠悬停 | avatar group hover |
头像/芯片行中悬停某项(距离衰减弹起) |
| 校验错误反馈 | error state shake |
表单错误/无效字段(分段 cubic-bezier 抖+自动回正) |
| 清空文本字段 | input clear with dissolve |
搜索框×/筛选重置(飞出+逐词 dissolve) |
| 占位→真实内容 | skeleton loader and reveal |
列表行/卡片加载后交叉淡入真实内容 |
| 进行中"活"文本 | shimmer text / thinking states |
加载标签/流式状态(循环扫光,纯 CSS) |
| 互斥选项移动高亮 | tabs sliding |
视图切换/分段控件(药丸指示跟随) |
| 悬停/聚焦提示 | tooltip open/close |
图标提示/信息泡(延迟淡入、即时退出) |
| 堆叠文字入场 | texts reveal |
主视觉/空状态/引导步(错落模糊升起) |
三、Motion Tokens:节奏一致性的来源
所有组件过渡共享一套语义化 timing token(不是魔法数字)——这才是"整站节奏一致"的真正机制,类比色彩/间距 token。
共享尺度(推荐基线,可据品牌微调)
/* Durations */
--duration-stagger: 40ms; /* 逐项错开偏移 */
--duration-micro: 80ms; /* tooltip/路径延迟、shake 段、大错开 */
--duration-quick: 150ms; /* modal/dropdown 关闭、text swap、tooltip 出现 */
--duration-fast: 250ms; /* icon swap、dropdown/modal 打开、tabs、page slide */
--duration-medium: 350ms; /* panel 关闭、toast 关闭 */
--duration-slow: 400ms; /* panel 打开、骨架揭示、input clear */
--duration-very-slow:500ms; /* 强调时刻、badge 出现、text reveal、success check */
/* Easings */
--ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1); /* 进出/位移/缩放通用 */
--ease-in-out: ease-in-out; /* icon/text/text-reveal/skeleton swap */
--ease-out: ease-out; /* tooltip */
--ease-linear: linear; /* shimmer/skeleton pulse/spinner */
--ease-bounce: cubic-bezier(0.34, 1.36, 0.64, 1); /* badge pop 打开 */
/* Distances / Scales / Blur */
--distance-base: 8px; --distance-medium: 12px; --distance-large: 30px;
--scale-small: 0.98; --scale-medium: 0.97; --scale-large: 0.96;
--blur-small: 2px; --blur-medium: 3px; --blur-large: 8px;
- 按"用途"而非"原始数值"映射:以用途对齐 token(如某关闭动效用 300ms 仍归
--duration-quick若用途为"modal close"),数字接近不强行替换。 - 每个过渡都自带
prefers-reduced-motion守卫(硬底线,删掉即过不了无障碍审计)。 - 低开销优先 + 最小 diff:只改必需文件,不引动效库;无框架依赖、粘贴即用。
- 禁止
transition: all:枚举精确属性,避免无关样式"搭便车"。
注:具体每个过渡的 CSS 片段、按组件覆盖的私有变量(如
--resize-dur、--badge-*)不在此段——那是 copy-paste 资产,随源站演进;需要时从官方取当前片段。本段只固「选型纪律 + 命名词汇 + token 体系」三层方法论。
补充 · GSAP 落地参考(库专用 · 仅 GSAP 载体时调用)
触发边界:本段仅在「载体 = 网页 / Web 应用,且已选定 GSAP 作为动效实现库」时调用。它不替代第八节「交互工程对错清单」与本节上半「存量审计 / 组件选型纪律」——那两条是通用纪律,本段是 GSAP 的具体写法落地。GSAP 当前全部插件免费(含原 Club 专属的 SplitText / MorphSVG,商业可用),从公共
gsapnpm 包安装即可。 来源:吸收自 greensock/gsap-skills(官方 GSAP AI 技能集,MIT),已去名化为通用写法骨架;具体 API 参数随 GSAP 版本演进,以官方文档当前版本为准。
一、何时选 GSAP 而非 CSS
- 需要时间线序列控制(多步编排)、运行时控制(暂停/反转/seek)、复杂缓动、滚动驱动(ScrollTrigger)、JS 动态计算值时用 GSAP;极简过渡用原生 CSS 即可,不引库。
二、核心 Tween 正确写法
- 属性名用 camelCase(
backgroundColor、rotationX)。 - 优先 transform 别名(
x/y/scale/rotation/xPercent)而非手写transform字符串——顺序一致、性能更稳、跨浏览器可靠。 autoAlpha优于opacity:值为 0 时自动visibility:hidden,避免隐形元素挡点击。- 全局默认节奏用
gsap.defaults({ duration: 0.6, ease: "power2.out" })收敛。
三、最易错点(AI 写 GSAP 的高频坑)
from()/fromTo()的immediateRender:同一元素同一属性堆叠多个from时,后者初始态会覆盖前者——给后者设immediateRender: false,保留第一个动画的终态。- 用 timeline + 位置参数代替
delay链:多步用gsap.timeline()与位置参数("+=0.2"/"-=0.1"/"<"/ 标签)编排,别用一串delay。 - ScrollTrigger 只能挂在顶级 tween / timeline 上,不能挂 timeline 内部的子 tween;
scrub与toggleActions不要同用一个触发器(scrub 胜出,逻辑冲突)。 - 横向滚动用
containerAnimation时子动画必须ease:"none",否则破坏滚动 1:1 映射。 - 布局变化(新内容 / 图片 / 字体 / 动态 DOM)后调用
ScrollTrigger.refresh();视口 resize 自动处理,动态内容不会。 - 生产移除
markers: true;所有插件使用前gsap.registerPlugin(...)注册一次。 - 清理:vanilla 用
gsap.context()或gsap.matchMedia()的revert()回收;高频更新属性用gsap.quickTo()复用单 tween,别每帧 new tween。
四、性能与降级(与第八节、第七节一致)
- 只动
transform/opacity(GPU 友好);will-change只给真正在动的元素;离屏动画 pause/kill。 - 无障碍:用
gsap.matchMedia()响应prefers-reduced-motion——reduceMotion条件为真时duration: 0或直接跳过,不位移不循环。与第七节「尊重 reduced-motion 是硬底线」同源。
五、常用 web 插件速查(仅 vanilla/web 相关)
| 插件 | 用途 | 一句话关键模式 |
|---|---|---|
| SplitText | 文本拆字/词/行做逐单位错开 | SplitText.create(".h",{type:"chars"}) → gsap.from(split.chars,{...stagger}) |
| CustomEase | 内置缓动不够时自定义曲线 | CustomEase.create("n",".17,.67,.83,.67") 作 ease |
| Flip | 布局状态间动画(FLIP 技术) | state=Flip.getState() → 改 DOM → Flip.from(state,{...}) |
| ScrollSmoother | 平滑滚动包装(需固定 DOM 结构) | 注册于 ScrollTrigger 之后;#smooth-wrapper > #smooth-content |
| ScrollToPlugin | 滚动到某元素/坐标(非 ScrollTrigger 场景) | gsap.to(window,{scrollTo:{y:"#sec"}}) |
| Draggable+Inertia | 拖拽与释放动量 | Draggable.create(".b",{type:"x,y",inertia:true}) |
| MorphSVG / MotionPath | SVG 形变 / 沿路径运动 | morphSVG:"#target" / motionPath:{path:"#p"} |
注:React/Vue/Svelte 框架适配、gsap.utils 辅助函数等不在此段(属框架/工具层);本段只固「易错纪律 + 关键骨架」,避免随版本过期。设计感网页的 GSAP 动效仍须先过第八节「该不该动 / 做对没有」与第五~七节「编排时刻 / 语义 / 性能降级」,GSAP 只是实现手段,不豁免设计纪律。