直接用 text-decoration: underline 无法实现中点展开动画,需用 ::after 伪元素配合 width 和 transform: translateX(-50%) 模拟;须设 position: absolute 与父容器 position: relative,并注意 IE 兼容性及换行限制。

为什么直接用 text-decoration: underline 不行
因为原生下划线是固定位置、固定长度的,没法控制起始点和动画方向。想让它从中间向两边展开,必须用伪元素模拟下划线——::after 是最稳妥的选择,它不干扰文本流,又能独立定位和动画。
::after 下划线的定位关键在 transform: translateX()
核心思路:让伪元素初始宽度为 0,水平居中;悬停时宽度撑满,同时用 transform: translateX(-50%) 配合 left: 50% 锚定中心点。否则容易偏移或抖动。
常见错误现象:::after 跑到文字上方、下划线不对齐、动画卡顿
- 必须设
position: absolute,父容器加position: relative -
width: 0和left: 50%同时存在时,transform: translateX(-50%)才能真正以文字中心为起点扩展 - 动画要用
width+transform,只动width会触发重排,影响性能
span {
position: relative;
display: inline-block;
}
span::after {
content: '';
position: absolute;
bottom: -2px;
left: 50%;
width: 0;
height: 2px;
background: currentColor;
transition: width 0.3s ease, transform 0.3s ease;
transform: translateX(-50%);
}
span:hover::after {
width: 100%;
}
兼容性坑:IE 不支持 transform 在 ::after 上动画
IE11 及更早版本对伪元素的 transform 动画支持极差,会出现闪动或不动。如果项目还需兼容 IE,得降级处理:
立即学习“前端免费学习笔记(深入)”;
- 放弃
transform,改用left和right控制伸展(但需固定父宽) - 或者干脆不动画,用
opacity淡入下划线作为 fallback - 现代项目建议直接忽略 IE,但上线前务必查
caniuse.com的::after+transform支持表
文字换行时下划线断开怎么办
::after 默认只作用于单行内联元素,遇到换行就失效。这不是 bug,是设计使然——伪元素绑定的是元素盒,不是文本流。
解决思路有限,没有完美方案:
- 强制单行:
white-space: nowrap(适合导航菜单等短文本) - 用
background-image: linear-gradient()模拟下划线(支持多行,但无法精确控制“中点展开”动画) - JavaScript 补位(监听
resize和load,动态计算每行位置插入 DOM 元素——太重,不推荐)
真正麻烦的是既要多行又要中点动画——这种需求本质上超出了 CSS 能力边界,得接受妥协。


















