使用styled-component实现数字递增动画 @property不生效如何解决
问题原因
@property是顶层CSS at规则,不支持嵌套在选择器内部编写,你把它写在strong选择器的样式块内,浏览器完全无法识别解析这个规则,自然不会生效。- 代码里
syntax属性的值错误转义了尖括号,写成了<integer>,就算把@property放到正确位置,浏览器也识别不到合法的类型声明,规则会直接失效。 - 仅定义
--num自定义属性没有任何动画效果,你还缺少变量插值动画、计数器绑定、数值渲染的相关逻辑,就算@property生效也看不到数字递增的效果。
正确实现方式
@property必须定义在全局样式作用域,不能嵌套在styled组件的选择器块里,可以借助styled-components提供的createGlobalStyleAPI完成全局声明,再配合CSS计数器和关键帧动画实现效果。
- 全局注册@property规则
import { createGlobalStyle } from 'styled-components'; // 全局定义支持整数插值的自定义属性--num const GlobalNumProperty = createGlobalStyle` @property --num { syntax: '<integer>'; initial-value: 0; inherits: false; } `
- 修改对应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; } } `
- 调整组件结构,引入全局注册的@property样式
<> <GlobalNumProperty /> <Info> <p> <strong></strong>User </p> </Info> </>
注意事项
- 该实现依赖CSS Houdini的
@property特性,在不支持该特性的低版本浏览器中会直接显示最终数值,没有平滑递增效果。如果需要全版本兼容,建议改用requestAnimationFrame驱动的JS数字递增方案。 - 如果页面有多个不同目标值的数字需要做递增效果,可以给
strong标签传入自定义props,动态生成动画的最终值,无需为每个数值单独写关键帧。
内容的提问来源于stack exchange,提问作者hse
相关产品推荐
相关产品推荐

