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

使用styled-component实现数字递增动画 @property不生效如何解决

问题原因
  • @property 是顶层CSS at规则,不支持嵌套在选择器内部编写,你把它写在strong选择器的样式块内,浏览器完全无法识别解析这个规则,自然不会生效。
  • 代码里syntax属性的值错误转义了尖括号,写成了<integer>,就算把@property放到正确位置,浏览器也识别不到合法的类型声明,规则会直接失效。
  • 仅定义--num自定义属性没有任何动画效果,你还缺少变量插值动画、计数器绑定、数值渲染的相关逻辑,就算@property生效也看不到数字递增的效果。
正确实现方式

@property必须定义在全局样式作用域,不能嵌套在styled组件的选择器块里,可以借助styled-components提供的createGlobalStyleAPI完成全局声明,再配合CSS计数器和关键帧动画实现效果。

  1. 全局注册@property规则
import { createGlobalStyle } from 'styled-components';

// 全局定义支持整数插值的自定义属性--num
const GlobalNumProperty = createGlobalStyle`
  @property --num {
    syntax: '<integer>';
    initial-value: 0;
    inherits: false;
  }
`
  1. 修改对应styled组件的样式,补全动画和计数器逻辑
const Info = styled.div`
  margin-left: 35rem;
  margin-top: -15rem;
  p {
    display: inline-block;
    width: 25rem;
    padding: 1rem;
    white-space: nowrap;
    overflow: hidden;
    font-weight: 500;
    strong {
      font-weight: 600;
      // 隐藏标签内硬编码的静态数字
      font-size: 0;
      // 将计数器和自定义属性--num绑定
      counter-reset: dynamicNum var(--num);
      // 触发数字递增动画,时长可按需调整
      animation: countUp 1.2s ease-out forwards;
      animation-delay: 0.2s;
      // 用伪元素渲染动态变化的数值
      &::before {
        content: counter(dynamicNum);
        font-size: initial; // 恢复正常字号
      }
    }
  }
  animation: ${ImgFade} 0.7s linear;
  animation-delay: 0.1s;

  // 数字递增关键帧,驱动--num从0过渡到目标值350
  @keyframes countUp {
    from {
      --num: 0;
    }
    to {
      --num: 350;
    }
  }
`
  1. 调整组件结构,引入全局注册的@property样式
<>
  <GlobalNumProperty />
  <Info>
    <p>
      <strong></strong>User
    </p>
  </Info>
</>
注意事项
  • 该实现依赖CSS Houdini的@property特性,在不支持该特性的低版本浏览器中会直接显示最终数值,没有平滑递增效果。如果需要全版本兼容,建议改用requestAnimationFrame驱动的JS数字递增方案。
  • 如果页面有多个不同目标值的数字需要做递增效果,可以给strong标签传入自定义props,动态生成动画的最终值,无需为每个数值单独写关键帧。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:30:51