纯 CSS 无法实现点击链接后自动收起导航栏,因 :focus-within 不响应点击后的焦点转移且移动端失效;唯一可靠纯 CSS 方案是二次点击汉堡按钮;若需点击链接收起,必须用极简 JS 监听并取消 checkbox 状态。

纯 CSS 方案无法在点击链接后自动收起导航栏,:focus-within 在此处不可靠——它不响应点击后的焦点转移,且移动端行为完全缺失。
为什么 :focus-within 不能用于收起菜单
很多人尝试用 .navbar:focus-within .nav-menu { display: block; } 控制展开,再指望点击 a 后因失去焦点自动收起。这在逻辑上就走不通:
-
:focus-within只在容器内任一子元素获得焦点时生效,但点击链接后焦点通常落在a自身,.navbar容器仍满足“内部有焦点”条件,不会触发收起 - 移动端点击不触发
:focus(无焦点概念),:focus-within直接失效 - 即使桌面端能短暂触发,页面滚动、切换标签页、按 Tab 键等都会意外改变焦点状态,导致菜单闪退或卡住
纯 CSS 方案的唯一合理收起方式:用户二次点击汉堡按钮
这是语义正确、无障碍友好、无需 JS 的底线方案。关键在于把“收起”明确交给用户操作,而非试图模拟点击后自动关闭:
- 确保
input#menu-toggle是隐藏复选框,label[for="menu-toggle"]精确关联 - 用
input#menu-toggle:checked ~ .nav-menu控制菜单显隐(注意是兄弟选择器,不是后代) - 收起动作就是再次点击 label → 切换
checked→ 菜单自然display: none - 不要加任何
:hover或:focus补丁——它们在触摸设备上不可预测,还会干扰键盘导航
如果真需要点击链接后收起,必须用极简 JS
这不是“增强”,而是功能刚需。只需监听链接点击,手动取消 checkbox 状态:
document.querySelectorAll('.nav-menu a').forEach(link => {
link.addEventListener('click', () => {
document.getElementById('menu-toggle').checked = false;
});
});
注意几点:
- 别用
querySelector('.nav-menu')后再遍历子a,容易漏掉动态插入的项;直接查全局更稳 - 确保
id="menu-toggle"和 HTML 中完全一致(大小写、连字符) - 这段 JS 必须在 DOM 加载完成后执行,推荐放在
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











