
本文详解如何纯 css 实现可点击展开的汉堡菜单:利用隐藏复选框 + :checked 伪类与相邻/兄弟选择器触发样式切换,兼容移动端,无需任何 javascript。
本文详解如何纯 css 实现可点击展开的汉堡菜单:利用隐藏复选框 + :checked 伪类与相邻/兄弟选择器触发样式切换,兼容移动端,无需任何 javascript。
在构建静态响应式网站时,许多初学者希望避免引入 JavaScript,但仍需实现现代交互效果——比如点击汉堡图标展开全屏导航菜单。CSS 本身虽无事件监听能力,但可通过 语义化表单控件()结合 :checked 状态伪类,巧妙模拟“开关”行为,实现完全基于 CSS 的菜单显隐控制。
核心原理:用复选框状态驱动样式切换
关键在于将 隐藏(opacity: 0),再通过其 :checked 状态,使用相邻选择器(+)和通用兄弟选择器(~)精准控制汉堡图标动画与菜单面板位移:
- ✅ #menu__toggle:checked + .menu__btn > span:旋转主横线为 45°(形成“×”的斜杠)
- ✅ #menu__toggle:checked + .menu__btn > span::before:上横线旋转至 0°(与主横线重合)
- ✅ #menu__toggle:checked + .menu__btn > span::after:下横线旋转 90°(与主横线垂直,构成“×”另一斜杠)
- ✅ #menu__toggle:checked ~ .menu__box:将菜单容器 left 从 -100% 移至 0,实现滑入效果
这种方案完全符合“CSS-only”要求,且具备良好的可访问性(屏幕阅读器可识别复选框状态)。
完整实现代码(含注释)
<!-- HTML:置于 <body> 开头,确保层级最高 --> <input id="menu__toggle" type="checkbox" /> <label class="menu__btn" for="menu__toggle"> <span></span> </label> <div class="menu__box"> <a class="menu__item" href="mailto:om@example.com">Mail</a> <a class="menu__item" href="./main.html">More to read here.</a> <a class="menu__item" href="contact.html">contact</a> </div>
/* CSS:关键部分(精简版,含必要注释) */
#menu__toggle {
opacity: 0;
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
z-index: -1; /* 确保不遮挡其他内容 */
}
.menu__btn {
position: fixed;
top: 20px;
left: 20px;
width: 26px;
height: 26px;
cursor: pointer;
z-index: 1000; /* 高于页面内容 */
}
.menu__btn > span,
.menu__btn > span::before,
.menu__btn > span::after {
display: block;
position: absolute;
width: 100%;
height: 2px;
background-color: #616161;
transition: transform 0.25s ease, top 0.25s ease;
}
.menu__btn > span::before { content: ""; top: -8px; }
.menu__btn > span::after { content: ""; top: 8px; }
/* 旋转动画:三线变 × */
#menu__toggle:checked + .menu__btn > span {
transform: rotate(45deg);
}
#menu__toggle:checked + .menu__btn > span::before {
top: 0;
transform: rotate(0deg);
}
#menu__toggle:checked + .menu__btn > span::after {
top: 0;
transform: rotate(90deg);
}
/* 菜单面板:初始隐藏在视口外 */
.menu__box {
position: fixed;
top: 0;
left: -100%;
width: 300px;
height: 100%;
background-color: #eceff1;
box-shadow: 2px 2px 6px rgba(0,0,0,0.4);
padding: 80px 0 0;
list-style: none;
transition: left 0.25s ease;
z-index: 999;
}
/* 展开状态:滑入视口 */
#menu__toggle:checked ~ .menu__box {
left: 0;
}
.menu__item {
display: block;
padding: 16px 24px;
color: #333;
font-family: 'Roboto', sans-serif;
font-size: 20px;
font-weight: 600;
text-decoration: none;
transition: background-color 0.2s;
}
.menu__item:hover {
background-color: #cfd8dc;
}
/* 桌面端:彻底隐藏汉堡按钮与菜单 */
@media (min-width: 601px) {
.menu__btn,
.menu__box {
display: none;
}
/* 同时恢复原底部导航栏可见 */
section.villan {
display: flex;
}
}注意事项与最佳实践
- 可访问性增强:为
- 移动端适配:建议在 中添加 ;
- 性能优化:所有动画均使用 transform 和 opacity(触发 GPU 加速),避免布局抖动;
- 样式隔离:.menu__box 使用固定宽高与 position: fixed,确保不干扰原有文档流;
- 降级友好:若 CSS 加载失败,复选框默认隐藏,用户仍可通过底部导航访问链接(保留功能完整性)。
通过此方案,你不仅获得了一个轻量、可靠、零 JS 的汉堡菜单,更深入理解了 CSS 状态驱动设计的底层逻辑——这正是现代 CSS 工程化的精髓所在。
立即学习“Java免费学习笔记(深入)”;










