用::after伪元素模拟删除线可实现宽度动画:容器设position:relative,::after设width:0、left:-10%、top:50%、transform:translateY(-50%),hover时width过渡至120%,避免text-decoration不可动画的限制。

用 ::after + width 动画实现动态删除线
直接用 text-decoration: line-through 无法做「从无到有」的宽度动画,因为 text-decoration-thickness 和 text-decoration-line 都不可过渡。必须用伪元素模拟删除线,并控制其 width 变化。
核心是:给文字容器加 position: relative,再用 ::after 绘制一条横线,初始 width: 0,hover 时过渡到 width: 120%,同时配合 left: -10% 实现左右延伸效果。
-
content: ""必须写,否则伪元素不渲染 -
display: block或inline-block才能设width和height - 用
top: 50%+transform: translateY(-50%)居中,比硬写top: 0.3em更稳 - 动画需显式声明
transition: width 0.4s ease-in-out,不能只靠transition-all
为什么 width: 100% 不够,非要 120% + left: -10%
伪元素默认以内容盒(content box)为基准计算 width: 100%,但删除线要覆盖文字两侧空白区域——比如字母 g、y 的下伸部分旁的空隙,或字体本身的字间距外延。若只设 width: 100%,线会刚好卡在文字最左/右边缘,看起来断开。
width: 120% 提供冗余长度,left: -10% 把整条线往左平移,让左侧多出 10%,右侧自然也多出 10%,视觉上就「贯穿」了。
立即学习“前端免费学习笔记(深入)”;
- 不同字体下沉程度不同,
-10%是通用起点;可微调至-5%或-15%适配具体字体 - 避免用
left: -20px这类固定值,响应式下易错位 - 若容器有
padding,需额外考虑是否把 padding 区域也纳入删除线范围
hover 动画没反应?检查这三处硬伤
常见现象:写了 transition,鼠标悬停却没动画。根本原因不是 CSS 写错,而是状态触发链断了。
- 没定义 hover 状态的终值:只写
.text::after { width: 0; transition: width 0.3s; }不够,必须补上.text:hover::after { width: 120%; } - 伪元素未脱离文档流:
position: absolute缺失 → 宽度动画被当作 inline 元素重排,不生效 - 父容器没设
position: relative→::after会相对于 body 定位,导致 left/top 偏移完全失控
兼容性与性能提醒
width 动画本身兼容性极好(IE9+),但要注意两个隐藏成本:
-
width是几何属性,触发 layout(重排),高频操作可能卡顿;如需大量使用,建议改用transform: scaleX()替代(需配合transform-origin: left center) - 旧版 Safari 对
transform: translateY(-50%)在伪元素上的支持不稳定,可降级为top: 0.32em(针对 16px 字体) - 若用户开启了系统「减少动态效果」(
@media (prefers-reduced-motion: reduce)),应主动关闭该动画,避免干扰


















