NextJS生产构建CSS关键帧渐变动画异常:百分比初始值丢失
问题:NextJS生产环境CSS@property变量异常导致动画失效
问题现象
- 开发环境中圆周填充动画正常,生产环境下动画无法平滑过渡,呈现大幅“步进”效果
- Chrome检查生产环境构建后的CSS时,
@property声明处提示“无效属性”错误,指向initial-value
排查发现
构建过程中生成的CSS文件里,@property的initial-value中的%被移除,变为initial-value:0,但原代码中设置的是百分比值(0%),这显然不符合预期。怀疑是webpack/postcss的问题?
相关代码
@property --p { inherits: false; initial-value: 0%; syntax: '<percentage>'; } .circle { width: 20px; height: 20px; /* 圆内空白区域 */ border: 5px solid transparent; /* 圆轮廓 */ box-shadow: 0 0 0 1px #fff; /* mask-image: radial-gradient(circle, transparent 0% 50%, black 50%); */ /* border: 2px solid white; */ border-radius: 50%; } .progressive-circle { aspect-ratio: 1; border-radius: 50%; --p: 0%; /* 降级方案 */ background: conic-gradient(#f8fafc var(--p), #0000 0); /* 使中心空白 */ mask-image: radial-gradient(circle, transparent 0% 70%, black 70%); position: relative; /* animation: continuous-circle var(--anim-duration) linear infinite var(--anim-delay); */ } @keyframes continuous-circle { 0% { --p: 0%; @apply opacity-0; } 1% { @apply opacity-100; } 33% { --p: 33.33%; } 66% { --p: 66.66%; } 98% { @apply opacity-100; } 100% { --p: 100%; @apply opacity-0; } }
疑问
- Chrome中
@property的“无效属性”错误原因是什么? - 该错误是否与生产环境的动画步进问题相关?
- 构建时
initial-value的%被移除是否是webpack/postcss的bug?
问题解答
核心原因
你遇到的问题确实和构建工具处理@property时的异常有关:
- NextJS默认用PostCSS处理CSS,其中的cssnano压缩插件在优化时,会错误地把
initial-value:0%里的%去掉,变成initial-value:0。而你定义的syntax: '<percentage>'要求值必须是百分比格式,所以Chrome会判定这个@property声明无效,直接忽略它。 - 当
@property无效时,CSS变量--p就会被当作普通字符串处理,而非可动画的百分比类型。普通变量无法实现平滑过渡,浏览器只能在关键帧节点直接切换值,没法插值计算中间状态,所以动画就变成了生硬的步进效果。
解决办法
- 禁用cssnano对
@property的压缩:在postcss.config.js里配置cssnano,跳过@property的处理。示例配置:
module.exports = { plugins: { 'postcss-import': {}, 'tailwindcss': {}, 'autoprefixer': {}, ...(process.env.NODE_ENV === 'production' ? { cssnano: { preset: [ 'default', { minifyParams: false, // 禁止处理参数里的单位 discardUnknown: false // 不要丢弃未知的@property规则 } ] } } : {}) } };
- 给
initial-value加引号:把initial-value:0%改成initial-value:"0%",这样压缩工具不会把%去掉,Chrome也能正确识别这个百分比值(单引号、双引号都可以)。 - 升级PostCSS相关插件:如果是插件版本bug,尝试更新cssnano、postcss到最新稳定版,看是否修复了这个问题。
验证方式
构建后检查生成的CSS文件,确认@property --p的initial-value仍为0%,此时Chrome的错误会消失,生产环境的动画也会恢复平滑过渡。
内容的提问来源于stack exchange,提问作者Gr33nLight
相关产品推荐
相关产品推荐

