因为border-bottom是盒模型属性,浏览器默认不支持过渡,必须显式在非hover状态下定义transition;正确做法是用::after伪元素配合position、transform:scaleX()和transition实现平滑伸长动画。

为什么.card-title:hover加border-bottom没动画
直接写 .card-title:hover { border-bottom: 2px solid #0d6efd; } 只会“啪”一下出现下划线,没有伸长过程——因为 border-bottom 是盒模型属性,浏览器默认不对其做过渡,必须显式声明 transition,且不能只写在 :hover 里。
用::after伪元素实现平滑伸长的关键三步
真正起效的最小组合是:父元素加定位、伪元素绝对定位 + transform: scaleX() + 过渡写在初始态。缺一不可:
-
.card-title必须加position: relative,否则::after会相对 body 定位,下划线飘走 -
.card-title::after要设content: ""、position: absolute、bottom: -4px(避开文字基线)、left: 0、width: 100%、height: 2px、background: #0d6efd - 初始态写
transform: scaleX(0); transform-origin: left center;和transition: transform 0.25s ease;;:hover里只写transform: scaleX(1);
移动端点按无反馈?别只靠:hover
iOS Safari 和多数安卓浏览器对 :hover 支持极弱,纯 CSS 方案在触摸设备上基本失效:
- 简单补救:
.card-title:active { transform: scaleX(1); },至少点按有响应 - 更稳妥方案:用 JS 在
touchstart时给.card-title加is-hovered类,touchend清除,CSS 写.card-title.is-hovered::after { transform: scaleX(1); } - 注意:不要用
transition: all,它会让文字颜色、边框等也参与过渡,干扰伸长效果
和 Bootstrap 卡片其他样式冲突怎么办
Bootstrap 5 的 .card-title 默认是 margin-bottom: 0.5rem,而你加的 ::after 在 bottom: -4px,容易被卡片内边距或阴影裁切:
- 确保
.card或.card-body没有overflow: hidden,否则下划线会被截断 - 如果用了
.text-center或.text-end,left: 0+width: 100%仍能对齐,但transform-origin: left center保证从左端开始伸长,不偏移 - 避免在
.card-title上直接写display: inline-block——它会破坏 Bootstrap 的流式排版,改用伪元素更安全
.card-title {
position: relative;
}
.card-title::after {
content: "";
position: absolute;
bottom: -4px;
left: 0;
width: 100%;
height: 2px;
background: #0d6efd;
transform: scaleX(0);
transform-origin: left center;
transition: transform 0.25s ease;
}
.card-title:hover::after,
.card-title.is-hovered::after {
transform: scaleX(1);
}
真正容易被忽略的是:过渡必须写在非 hover 的初始规则里,而且 transform-origin 的取值直接影响伸长起点——写成 right center 就会从右往左伸,不是常规预期。


















