在 Codex 主题里用 CSS 动画:好看与不卡的分界线
2026-10-04
Codex 主题里加 CSS 动画,最容易翻车的不是写法,而是克制。主题 CSS 通过本机 CDP 注入到渲染进程,动画跑在和界面同一层,所以一段写坏的 keyframes 会直接拖慢输入框和滚动。这篇讲哪些动效值得加、数值怎么定,以及怎么看出来它开始拖后腿。
哪些动画值得做
判断标准只有一条:这个动效是否帮你看清状态。面板滑入、焦点环呼吸、切换主题时的淡入属于这一类;背景无限旋转、满屏粒子、常驻的发光脉冲属于另一类。后者在第一分钟好看,第三小时开始分神。
- 值得加:面板和侧栏的入场位移、焦点环与激活态过渡、主题切换的淡入淡出、加载态的轻微呼吸
- 谨慎加:背景位移或缩放、长期运行的渐变流动、任何盖在文本上的动画
- 别加:无限旋转的背景、粒子效果、跟随鼠标的大范围位移
动画数值怎么定
时长和缓动决定观感。界面元素位移用 160 到 240 毫秒,淡入淡出用 120 到 200 毫秒,循环呼吸用 2.4 到 4 秒。位移超过 300 毫秒,鼠标已经移开了界面还在动,主观上就变成卡顿。
- 位移:160 到 240ms,ease-out
- 淡入淡出:120 到 200ms,linear 或 ease
- 循环呼吸:2.4 到 4s,ease-in-out,alternate
- 缓动曲线:优先 cubic-bezier(0.2, 0, 0.2, 1),短时长下比 ease-in-out 干净
只动不会触发重排的属性
性能的分水岭在属性选择。transform 和 opacity 走合成层,浏览器可以把它们交给 GPU,主线程空出来处理你的输入。width、height、top、left、box-shadow、filter 这类属性每帧都要重算布局和绘制,在输入框里连续打字时立刻能感觉到掉帧。
- 安全:transform(translate / scale / rotate)、opacity
- 要小心:box-shadow、filter: blur()、background-position
- 避免:width 和 height、top 和 left、margin、border-width
尊重系统的减弱动效设置
有一部分用户开了系统级的减弱动态效果,原因可能是前庭敏感,也可能只是不想被晃。用 @media (prefers-reduced-motion: reduce) 把这些动画降到 0.01ms 或者直接关掉,就是几行代码的事,但它决定了这批用户能不能用你的主题。
- 纯装饰的动画整段关掉
- 功能性过渡保留,时长压到 100ms 以内
- 关掉之后确认静态终态是对的,不要让元素直接消失
怎么判断动画开始拖后腿
写完不要只靠感觉。打开 Codex,滚动一段长会话,在输入框连续打字,再切换几个主题,看有没有掉帧。想更客观一点,用 DevTools 的 Performance 面板录五秒,看主线程有没有被动画帧反复占满。
- 打字时输入框有延迟:动画在动布局属性
- 滚动掉帧:背景在跑 blur 或大范围位移
- 切换主题后卡一下:有多个长循环动画同时启动
- 风扇转起来:动画在持续占用主线程
一份能直接用的起点
从这四条开始,再按自己的主题改数值。它们只碰 transform 和 opacity,也带了减弱动效的分支。
- .panel { transition: transform 200ms cubic-bezier(0.2, 0, 0.2, 1), opacity 160ms linear; }
- @keyframes breathe { from { opacity: 0.55 } to { opacity: 0.85 } }
- .focus-ring { animation: breathe 3s ease-in-out infinite alternate; }
- @media (prefers-reduced-motion: reduce) { .focus-ring { animation: none } }
动画是主题的语气,不是主题的体积。把动效留给状态变化,把静止留给背景,长时段使用才会舒服。
常见问题 FAQ
Codex 主题里能写 CSS 动画吗?
能。主题包里的 CSS 通过 CDP 注入渲染进程,@keyframes、transition、animation 都可以用。限制在安全层面:主题包只允许 CSS 和图片,不允许 JavaScript。
动画会让 Codex 变卡吗?
写法正确就不会。只动 transform 和 opacity 时动画走合成层,主线程留给输入和滚动。动 width、box-shadow、filter: blur() 这类属性会触发重排和重绘,打字与滚动时能明显感觉到掉帧。
背景图能动吗?
可以,但代价偏高。background-position 或 background-size 的动画每帧都要重绘背景层,大图上尤其明显。想要动感,用一张静态图加一层低透明度的渐变遮罩动画,比直接动图便宜得多。
怎么让动画尊重系统设置?
用 @media (prefers-reduced-motion: reduce) 把装饰性动画关掉,功能性过渡压到 100ms 以内。这个媒体查询读的是系统级的减弱动态效果开关,不需要用户在工具里再设一次。