Bootstrap 不自动管理 .active 状态,需手动用 JS 切换;.nav-link 和 .list-group-item 对 .active 的应用结构不同,必须严格遵循层级与基础类要求,并同步 aria-current 以保障可访问性。
bootstrap 本身不自动管理点击后的激活状态,.active 类必须手动添加或移除——这不是 bug,是设计使然。所有“点击高亮”效果,都得靠你自己写 js 控制 class 切换。
为什么点击后 .active 不自动保留
因为 Bootstrap 的 .active 是纯 CSS 类,没有内置状态监听逻辑。页面刷新、跳转、甚至只是点击一下链接,都不会自动维持它。浏览器不会记住你点过谁,除非你显式操作 DOM。
- 常见错误:只给 HTML 写死
<li class="list-group-item active">,结果切换页面后高亮消失 - 服务端渲染时可由后端判断当前路径并注入
.active;前端 SPA 则必须监听路由变化再更新 -
:hover和:focus是瞬时伪类,不能替代.active表达“当前选中”语义
.nav-link 和 .list-group-item 的激活结构差异
两者都依赖 .active,但生效前提不同:
-
.nav-link必须是.nav-item的直接子元素,且.active要加在.nav-link上(不是.nav-item) -
.list-group-item必须存在基础类,否则.active样式不触发;若用<a></a>标签,还需加.list-group-item-action - 下拉菜单中,
.active应加在.dropdown-toggle上,而非.dropdown-menu容器
用原生 JS 安全切换 .active 类的写法
避免 querySelector('.active') 返回 null 导致 remove() 报错:
document.querySelectorAll('.nav-link').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
// 移除所有 active
document.querySelectorAll('.nav-link').forEach(l => l.classList.remove('active'));
// 给当前加 active
this.classList.add('active');
// 可选:同步更新内容区或 URL
const target = this.getAttribute('href');
if (target && target.startsWith('#')) {
document.querySelector(target).scrollIntoView({ behavior: 'smooth' });
}
});
});
- 不要用
!important强行覆盖样式优先级,改用更具体选择器,例如:.navbar-nav > .nav-item > .nav-link.active - 如果用了
aria-current="page",记得同步更新它的值(设为"page",不是"true") - 移动端真机测试时注意:iOS Safari 可能延迟触发
click,可加touchstart备用事件
最容易被忽略的是语义与结构的一致性:哪怕样式看起来对了,如果 .active 加在错误层级、漏掉基础类、或没配 aria-current,对键盘用户和屏幕阅读器就是不可用的。











