font-size transition 多数情况下无效,因浏览器不对 font-size 插值计算,尤其单位混用、含 0 或继承值时直接跳变;推荐方案依次为 transform: scale()、CSS 自定义属性 + calc()、JavaScript 手动逐帧更新。
直接写 transition: font-size 0.3s 多数情况下无效——不是你代码写错了,而是浏览器根本不会对 font-size 做插值计算,尤其在单位混用、含 0 或继承值(inherit、unset)时会直接跳变。
浏览器只对「能明确算出中间值」的属性做过渡。而 font-size 在以下情况无法插值:
16px → 1.2em
0、auto、initial、inherit
font-size 动态变化,子元素用 em 导致计算链断裂font-size(靠继承得来),transition 没有起点首选:用 transform: scale() 模拟字号变化
display: inline-block 或 block,否则 transform-origin 不生效transform-origin: top left 可避免文字上跳,适合标题/按钮等不牵连布局的场景font-size 和 scale(),否则字体模糊示例:
立即学习“前端免费学习笔记(深入)”;
.text { display: inline-block; transform-origin: top left; transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);}.text:hover { transform: scale(1.25);}
次选:CSS 自定义属性 + calc()(Chromium 110+ / Firefox 111+)
--fs-multiplier,再写 font-size: calc(var(--fs-multiplier) * 1rem)
@property 注册该变量为可动画类型,否则 transition 无效兜底:JavaScript 手动逐帧更新(兼容老浏览器)
requestAnimationFrame 控制每帧 element.style.fontSize
style.fontSize——会强制同步布局,严重掉帧这些常见做法实际不可靠:
transition: all 0.3s —— 会意外过渡 margin、border 等,引发布局抖动font-size: 0 开始过渡 —— 几乎所有浏览器都不支持 0 → 非零插值em 单位但父级字号也在变 —— 子元素过渡不同步,视觉卡顿display: none 元素加 transition —— 完全不触发,因为元素已脱离渲染流真正难的不是让字“动起来”,而是想清楚:你要动的是「排版尺寸」(影响布局、需真实改变 font-size),还是「视觉尺寸」(只求看起来变大,用 transform 更稳)。前者极少需要动画,后者才是日常高频需求。