浏览器不支持 text-decoration 属性动画,需用 ::after 伪元素模拟:设 content: ""、父元素 position: relative,::after 用 transform: scalex() 和 transform-origin 实现顺滑下划线,多行文本需 inline-block 布局。

为什么不能直接动画 text-decoration
浏览器对 text-decoration 的动画支持极差:text-decoration-thickness 和 text-underline-offset 在绝大多数场景下无法触发 transition 或 @keyframes,CSS 引擎会静默忽略。你写上 transition: text-decoration-thickness 0.3s,它就是不动——不是写错了,是规范本身不允许可动画。
::after 必须设 content: "" 且父元素 position: relative
伪元素默认不渲染,content: "" 是硬性前提;否则再怎么调 width 或 transform 都没用。同时,::after 若未定位到正确上下文,会相对于 偏移,导致线条飘走。
- 父容器(比如
<a></a>或<h2></h2>)必须声明position: relative -
::after要设position: absolute、bottom: -2px(或0.0625em等相对单位),避免受line-height或padding干扰 - 高度别写死成
1px,用0.0625em更适配不同字号
用 transform: scaleX() 而非 width 动画
width 变化会触发重排(reflow),尤其在滚动或复杂布局中容易卡顿;transform: scaleX() 只走合成层,GPU 加速,顺滑得多。但关键细节常被跳过:
- 初始态必须是
transform: scaleX(0),不是scaleX(1)再缩回 - 必须显式写
transform-origin: left center(从左往右展开)或50% 100%(居中贴底展开)——漏掉就默认center center,线条从中间“炸开” -
transition必须写在::after的默认样式里,不能只写在:hover::after中,否则首次悬停无动画
多行文本下划线对齐要改 display
纯 inline 元素的 ::after 只能作用于第一行末尾,换行后就断了。解决办法很具体:
- 把文字容器设为
display: inline-block(不是block,否则破坏流式布局) -
::after设left: 0; right: 0; width: 100%或直接靠transform: scaleX()撑满,不依赖父宽计算 - 若内容动态加载或字体变化频繁,得用
ResizeObserver监听尺寸并重置伪元素宽度(width方案)或强制重绘(transform方案更稳)
letter-spacing、font-variant 或不同字体时,伪元素的 baseline 总是轻微偏移——这得靠微调 bottom 值,而且每个字体都得单独测。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











