本文详解如何修复纯 css 实现的汉堡菜单在关闭时无过渡动画的问题,通过合理设置 `opacity`、`visibility` 和 `transition` 属性,并修正伪类选择器逻辑,确保打开与关闭均具备一致、流畅的视觉动效。
在使用纯 CSS + 控制的响应式导航菜单中,一个常见问题是:菜单打开时有过渡(transition)效果,但关闭时却瞬间消失——这通常源于对 CSS 过渡触发条件和初始/终态样式的误配。
核心问题在于你尝试使用的规则:
.navigation__checkbox:not(checked) ~ .navigation__nav .navigation__list { opacity: 1; }❌ 这是无效的::not(checked) 并非标准 CSS 伪类(正确写法应为 :not(:checked)),且该选择器逻辑错误——它试图在未勾选时强制显示列表,反而破坏了“关闭即隐藏”的预期行为。
✅ 正确思路是:让菜单容器(.navigation__nav)和内部列表(.navigation__list)都具备可过渡的视觉属性(如 opacity、width、visibility),并在 :checked 状态下显式定义「展开态」,其余状态则保持「收起态」。
以下是关键修复要点与推荐实现:
确保 .navigation__nav 和 .navigation__list 在默认(未勾选)状态下具有可动画的隐藏值,并声明 transition:
.navigation__nav {
position: static;
height: 100vh;
background-color: #ffffff;
opacity: 0;
width: 0;
visibility: hidden; /* 配合 opacity 实现完全隐藏 */
transition: opacity 1s ease, width 1s ease, visibility 1s;
}
.navigation__list {
opacity: 0;
transition: opacity 1s ease;
}⚠️ 注意:仅靠 opacity: 0 不足以阻止用户点击或聚焦(需配合 visibility: hidden 或 pointer-events: none);visibility 本身不可过渡,因此我们用 transition: visibility 1s 是无效的——实际应通过 opacity + visibility 组合 + transition-delay 巧妙控制,或更稳妥地用 max-height/transform 替代(见进阶建议)。
删除所有 :not(checked) 相关样式,只保留正向逻辑:
.navigation__checkbox:checked ~ .navigation__nav {
width: 100%;
opacity: 1;
visibility: visible;
}
.navigation__checkbox:checked ~ .navigation__nav .navigation__list {
opacity: 1;
}这样,当复选框被取消勾选时,CSS 自动回退到初始 opacity: 0 和 width: 0,并因 transition 存在而自然淡出+收缩。
保证兄弟选择器生效确保 与 .navigation__nav 处于同一父级层级,且 .navigation__nav 确实是 的后续兄弟元素(~ 选择器要求):
打开/关闭菜单时,应看到:
只要严格遵循「初始隐藏 + transition 声明 + :checked 显式展开」三原则,即可彻底解决关闭无过渡的顽疾。