You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
  }
}

疑问

  1. Chrome中@property的“无效属性”错误原因是什么?
  2. 该错误是否与生产环境的动画步进问题相关?
  3. 构建时initial-value的%被移除是否是webpack/postcss的bug?

问题解答

核心原因

你遇到的问题确实和构建工具处理@property时的异常有关:

  • NextJS默认用PostCSS处理CSS,其中的cssnano压缩插件在优化时,会错误地把initial-value:0%里的%去掉,变成initial-value:0。而你定义的syntax: '<percentage>'要求值必须是百分比格式,所以Chrome会判定这个@property声明无效,直接忽略它。
  • 当@property无效时,CSS变量--p就会被当作普通字符串处理,而非可动画的百分比类型。普通变量无法实现平滑过渡,浏览器只能在关键帧节点直接切换值,没法插值计算中间状态,所以动画就变成了生硬的步进效果。

解决办法

  1. 禁用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规则
          }
        ]
      }
    } : {})
  }
};
  1. 给initial-value加引号:把initial-value:0%改成initial-value:"0%",这样压缩工具不会把%去掉,Chrome也能正确识别这个百分比值(单引号、双引号都可以)。
  2. 升级PostCSS相关插件:如果是插件版本bug,尝试更新cssnano、postcss到最新稳定版,看是否修复了这个问题。

验证方式

构建后检查生成的CSS文件,确认@property --p的initial-value仍为0%,此时Chrome的错误会消失,生产环境的动画也会恢复平滑过渡。


内容的提问来源于stack exchange,提问作者Gr33nLight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 05:40:37