导航链接下划线动画由自定义的 .nav-link::after 伪元素类控制,通过 width 过渡实现;Bootstrap 5 原生不提供该动画。
导航链接下划线动画由哪个 CSS 类控制
bootstrap 5 的导航项(.nav-link)默认没有悬停下划线,你看到的下划线大概率来自自定义样式或第三方插件。原生 bootstrap 只对 .nav-link 设置了 text-decoration: none,且 hover 时仅改变颜色,不触发下划线动画。
真正起作用的是你自己写的 :hover::after 或 border-bottom 动画规则。检查浏览器开发者工具里 .nav-link:hover 或其伪元素的样式来源,90% 的情况是项目里已有类似这样的代码:
.nav-link::after {
content: '';
display: block;
width: 0;
height: 2px;
background: #0d6efd;
transition: width .3s ease;
}
.nav-link:hover::after {
width: 100%;
}
覆盖默认下划线动画的正确写法
不要试图修改 Bootstrap 源码或用 !important 硬顶,而是用更精确的选择器优先级覆盖。关键点是:必须同时重写伪元素的初始态、过渡属性和 hover 态。
- 确保
::after的position: absolute和父容器position: relative配合,否则下划线位置飘移 -
transition必须写在初始态(非 hover 态),否则动画不触发 - 避免用
border-bottom+transform: scaleX()混搭,容易因盒模型计算出错导致动画跳变 - 如果导航项有 padding,下划线需用
bottom: 0+left: 0定位,别依赖 margin
推荐写法:
.nav-pills .nav-link,
.nav-tabs .nav-link {
position: relative;
}
.nav-pills .nav-link::after,
.nav-tabs .nav-link::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: #dc3545;
transition: width .25s cubic-bezier(.4,0,.2,1);
}
.nav-pills .nav-link:hover::after,
.nav-tabs .nav-link:hover::after {
width: 100%;
}
为什么改了 CSS 但动画还是不生效
常见原因不是语法错,而是被其他样式拦截或条件未满足:
-
.nav-link被包裹在<a>外又套了<li>,结果你写的::after生成在<li>上,但定位参考的是<a>—— 检查 computed styles 里的position和offsetParent - Bootstrap 的
.active类设置了border-bottom: 2px solid #0d6efd,和你的::after下划线重叠,视觉上“卡顿”—— 给.nav-link.active::after加display: none - 用了
rem或em单位定义height,但在根字体缩放后下划线变细或消失——统一用px - CSS 文件加载顺序错,你的样式表在 Bootstrap 之后但被更高优先级的组件样式覆盖——用
devtools → Styles 面板看哪条规则被 strike-through
移动端点击后下划线残留怎么处理
真机上点击导航项会触发 :active 状态,部分安卓 WebView 会把 :hover 效果“冻结”一帧,导致下划线不收回去。这不是 bug,是触摸事件模拟 hover 的副作用。
解决方法很简单,加一行重置:
.nav-link:active::after {
width: 0 !important;
}
或者更稳妥地,在 JS 里监听 touchstart 并临时移除 hover 类(但多数场景没必要,直接用上面的 CSS 就够了)。
真正麻烦的是混合使用 pointer-events: none 或禁用链接的场景——此时 :hover 不触发,你的下划线动画自然失效,得换用 JS 控制类名。


















