纯 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 直接失效这是语义正确、无障碍友好、无需 JS 的底线方案。关键在于把“收起”明确交给用户操作,而非试图模拟点击后自动关闭:
input#menu-toggle 是隐藏复选框,label[for="menu-toggle"] 精确关联input#menu-toggle:checked ~ .nav-menu 控制菜单显隐(注意是兄弟选择器,不是后代)checked → 菜单自然 display: none
:hover 或 :focus 补丁——它们在触摸设备上不可预测,还会干扰键盘导航这不是“增强”,而是功能刚需。只需监听链接点击,手动取消 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 中完全一致(大小写、连字符)</body> 前,或包裹在 DOMContentLoaded 里blur() 或 removeAttribute('href') 等旁门左道——它们破坏可访问性,且对 SPA 路由无效哪怕 JS 写对了,以下三点仍会让收起失效:
input#menu-toggle 若用了 display: none,部分旧版 Safari 会忽略其 :checked 状态变化,务必补上 position: absolute; left: -9999px;
overflow: hidden 或 transform(如 transform: translateZ(0)),会创建新层叠上下文,导致 JS 修改 checked 后 CSS 规则不重绘——检查并移除这些属性a 都绑定同一段收起逻辑,否则点一个全关;应按菜单作用域分别处理