:checked伪类是纯css实现点击切换的核心,需配合隐藏复选框、id绑定的label及后续兄弟菜单容器,用#menu-toggle:checked~.menu-items控制显隐,并通过transform/opacity等可过渡属性实现动画。

:checked 伪类是纯 CSS 实现点击切换的核心,不依赖 JS 就能完成“点开 → 显示菜单”“再点 → 隐藏菜单”的完整闭环。但必须配合隐藏复选框 + 精准的兄弟/相邻选择器,否则样式不会响应。
用 <input type="checkbox"> 做状态开关,别用 <button></button> 或 <div>
<p>浏览器原生只对表单控件(如 <code>checkbox)提供 :checked 状态,用其他元素无法触发该伪类。常见错误是试图给 <div class="hamburger"> 加 <code>:active 或自定义 data-open,这在纯 CSS 场景下完全无效。
正确结构必须包含:
- 一个
<input id="menu-toggle" type="checkbox">(不可省略id) - 一个关联它的
<label for="menu-toggle"></label>,作为可点击区域(图标就放里面) - 菜单容器(如
<nav class="menu-items"></nav>)必须是input的后续兄弟节点,且用~(通用兄弟选择器)或+(相邻兄弟选择器)定位
#menu-toggle:checked ~ .menu-items 是显隐控制的关键选择器
很多初学者写成 .menu-toggle:checked ~ .menu-items(漏了 #),或把菜单放在 label 内部——这两者都会导致样式不生效。CSS 选择器必须严格匹配 DOM 层级关系。
典型结构顺序应为:
<input id="menu-toggle" type="checkbox"><label for="menu-toggle"><span></span><span></span><span></span></label> <nav class="menu-items">...</nav>
这样才可用 #menu-toggle:checked ~ .menu-items 控制显隐。若菜单在 label 内,则无法被 ~ 选中;若 input 没 id,label 就无法绑定,点击也不会触发状态变化。
动画和图标变形必须用 transition + transform,别只靠 display
display: none / block 无法过渡,会导致菜单突显突隐。所有动效必须基于可过渡属性:比如 left、opacity、transform、max-height(注意 max-height 从 0 到具体值需预设足够大数值,否则动画卡顿)。
汉堡图标变叉(X)的常见写法:
- 三根
<span></span>均设position: absolute和相同尺寸 - 第一根:旋转
45deg+ 向右上平移(模拟 X 左上斜线) - 第二根:
opacity: 0(直接隐藏中间横线) - 第三根:旋转
-45deg+ 向右下平移(模拟 X 右下斜线) - 所有变换都加
transition: transform 0.3s, opacity 0.3s
移动端适配要靠媒体查询,但别在 @media 里重写整个逻辑
桌面端应默认显示完整导航栏,移动端才启用汉堡菜单。这意味着:
-
.menu-items在桌面端设为display: flex,且input和label设为display: none - 在
@media (max-width: 768px)中,仅让.menu-items改为position: fixed+left: -100%,同时显示label - 不要在媒体查询里重复定义
:checked规则——它全局有效,只需确保 DOM 结构始终存在
容易忽略的一点:如果菜单内容高度超过视口,又没设 overflow-y: auto,用户会无法滚动查看底部链接。这个细节纯 CSS 方案里常被遗漏。











