
本文详解如何纯 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免费学习笔记(深入)”;