浏览器不支持 text-decoration 动画因其属离散型属性;最稳方案是 ::after + transform: scaleX(),需设 position、transform-origin 等关键属性;多行下划线 CSS 无解,须用 background 或 JS。

为什么不能直接用 text-decoration: underline 做动画
浏览器对 text-decoration 及其子属性(如 text-underline-offset、text-decoration-thickness)的动画支持极弱——绝大多数情况下,transition 会静默失效。这不是写法问题,是规范限制:这些属性被定义为“离散型”,不参与 CSS 动画插值计算。
::after 伪元素 + transform: scaleX() 是最稳方案
核心逻辑是:用 ::after 画一条横线,初始缩放为 0,悬停时展开到 1。相比改 width,scaleX() 不触发重排,动画更顺,且天然支持中心展开。
关键配置必须齐备:
- 父元素设
position: relative -
::after设position: absolute; bottom: -2px; left: 50%; transform-origin: center center; - 初始状态:
transform: scaleX(0); - 悬停状态:
transform: scaleX(1); - 动画用
transition: transform 0.3s ease;
漏掉 transform-origin: center center,默认缩放中心在左上角,线条会偏移或斜拉;设成 center center 才能真正从文字中点向两边同步伸展。
立即学习“前端免费学习笔记(深入)”;
用 width + left 模拟中间展开要格外小心
这种写法靠同时控制 left: 50% → left: 0% 和 width: 0 → width: 100% 实现视觉上的“中点展开”,但实际是左端固定、右端拉伸,只是人眼误判为对称。
常见翻车点:
- 没给父元素设
overflow: hidden,初始width: 0时因字体撑开导致伪元素轻微位移,动画起始抖动 -
::after缺少display: block或inline-block,width在 inline 元素上无效 - 没配
transform: translateX(-50%)就直接调left: 50%,结果下划线中心没对准文字中心,尤其在字号变化或letter-spacing存在时明显偏移
多行文本下划线展开的兼容性现实
所有基于 ::after 的单伪元素方案,本质上都只作用于**首行**——因为伪元素是绝对定位在父容器底部的,无法自动跟随换行位置。若需真正支持多行(比如段落悬停整段加动态下划线),得放弃伪元素,改用 background-image 配合 background-size 和 background-position 逐行控制,或者用 JS 计算每行 getBoundingClientRect() 后动态插入多个伪元素。
换句话说:想“看起来像多行展开”,可以用渐变背景模拟;想“精确控制每一行起止”,CSS 目前无解,必须引入 JS。


















