bootstrap 5 中直接用 text-decoration-underline 无效,因其被 a 标签默认的 text-decoration: none 覆盖,且该属性无法控制颜色、粗细、位置及动画;需用 .card-title::after 配合 position: relative、transform: scalex() 和正确 transform-origin 实现精准下划线动画。

为什么直接用 text-decoration-underline 不行
Bootstrap 5 默认对所有 a 标签设了 text-decoration: none(在 _reboot.scss 里),所以即使你加了 text-decoration-underline 工具类,它也会被覆盖。更关键的是:text-decoration 无法控制颜色、粗细、位置、动画起始点,也不能做“从左到右展开”这种交互效果。
.card-title::after 必须配 position: relative
这是最常被忽略的一步。伪元素 ::after 默认相对于最近的已定位祖先定位;.card-title(通常是 <h5></h5>)默认是 static 定位,不构成“已定位祖先”。结果就是下划线会飘到 body 顶部或左上角——你看到“没反应”,其实是它错位了。
- 必须显式写
.card-title { position: relative; } - 不要写成
.card:hover .card-title::after,那会要求整个卡片悬停才触发,不符合“仅标题响应鼠标”的需求 - 如果用了自定义 class 如
.my-card,选择器得写成.my-card .card-title::after,否则权重不够,被 Bootstrap 原生样式压住
用 transform: scaleX() 而不是 width 动画
width 动画在 inline 元素(比如默认的 .card-title)上无效,还会触发重排(reflow),移动端卡顿明显。transform: scaleX() 只触发重绘(repaint),GPU 加速更顺滑,且能精准控制缩放起点。
- 初始态写
transform: scaleX(0); transform-origin: left center; - hover 态写
transform: scaleX(1); -
transition必须写在初始态(非 hover 态),例如transition: transform 0.25s ease;,否则动画不触发 - 别混搭
border-bottom和transform——边框本身不支持缩放,容易跳变
下划线错位或被裁剪的常见原因
不是代码写错了,而是布局干扰导致的视觉失效:
-
.card-header或.card-body设了overflow: hidden—— 下划线被直接裁掉,临时改成overflow: visible就能验证 -
.card-title外层被包在<div> 里但没设 <code>display: inline-block或inline-flex—— 导致width: 100%拉满整行,而不是贴合文字宽度 - 字体用了
text-transform: uppercase,但transform-origin还是left center—— 改成left bottom才能对齐大写字母基线 -
bottom: 0看起来合理,但实际受字体 descender(如 g、y 的下延部分)影响,推荐用bottom: -0.25rem更稳
真正难的不是写出第一版动画,而是当它在某个卡片里突然不显示、或在 Safari 里偏移 2px、或在响应式折叠后错位时,你能立刻想到该去检查
overflow、display、transform-origin 这三个地方。











