purgecss默认不删@keyframes,因其核心逻辑仅匹配dom选择器类名、id等,而@keyframes名称仅为animation-name引用标识符,需显式启用keyframes: true并配合完整content路径扫描和必要safelist才能识别清理。

为什么PurgeCSS默认不删@keyframes?
PurgeCSS 的核心逻辑是「字符串匹配类名、ID、属性选择器」,而 @keyframes 名称本身不参与 DOM 选择器匹配,它只是被 animation-name 引用的标识符。因此即使某个 @keyframes slide-in 完全没被任何 CSS 规则或 JS 调用,PurgeCSS 也不会主动识别并删除它——除非你显式配置它去扫描 animation-name 的值。
如何让PurgeCSS识别并清理未用的@keyframes?
关键在 @fullhuman/postcss-purgecss 的 keyframes: true 选项,它会强制插件提取所有 animation-name 值,并与 @keyframes 名称比对:
- 必须启用
keyframes: true,否则无论怎么配 content 都无效 -
content字段仍需完整覆盖 HTML/JS 模板路径,否则animation-name: "bounce"这类字符串根本不会被扫描到 - 若 JS 动态拼接动画名(如
el.style.animationName = 'fade-' + type),必须在safelist中加正则,例如/^fade-.+$/ - Tailwind 用户注意:其
animate-bounce类底层仍依赖@keyframes bounce,所以 PurgeCSS 的keyframes扫描对 Tailwind 项目同样必要
Chrome Coverage 工具能替代 PurgeCSS 吗?
不能,二者定位不同:
-
chrome://devtools/coverage只能告诉你「哪些 CSS 字节在当前页面加载和交互中从未执行过」,但它无法区分是@keyframes未被引用,还是仅因用户没触发某分支而未运行 - 它对伪元素动画(
::before中的animation-name)支持不稳定,容易漏报 - 它不生成可复用的清理结果,无法集成进 CI 或构建流程
- 真正可靠的方案是「Coverage + PurgeCSS 双验证」:Coverage 发现可疑未用帧,再查 PurgeCSS 的
removedSelectors日志确认是否被静态识别
常见误删和排查要点
删掉关键帧后动画直接消失,但控制台无报错,这是最典型的静默失效:
- 检查 PurgeCSS 输出日志里是否有类似
Removed @keyframes bounce的条目;若有,说明它确实没在content文件里找到"bounce"字符串 - 确认 JS 中写的是字面量
animationName = "bounce",而非变量拼接或模板字符串(后者可能被构建工具混淆或剥离) - Vue/Svelte 等框架中,
v-if分支内的class="animate-bounce"若未在首次渲染时激活,PurgeCSS 会忽略该字符串——必须把对应组件路径加入content - PostCSS 插件顺序很重要:
@fullhuman/postcss-purgecss必须放在cssnano之前,否则cssnano的reduceIdents可能重命名@keyframes,导致 PurgeCSS 匹配失败
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











