纯HTML无法实现导航栏折叠/展开,必须依赖CSS的:checked伪类、@media查询或JavaScript;零JS方案需用checkbox+~选择器配合max-height过渡,JS方案应使用classList.toggle()而非直接操作style。
纯 HTML 无法实现导航栏的折叠/展开行为——它只提供语义骨架,
、
、
标签本身不带任何交互逻辑。真正起作用的是 CSS 的
伪类、
查询,或 JavaScript 的类名切换。选哪条路,取决于你是否允许 JS 加载失败时菜单完全不可用。
为什么不能只用
+ 媒体查询做移动端切换
媒体查询能控制「何时隐藏」,但解决不了「用户点一下怎么让它出来」。常见错误是:小屏下把
设为
,再写个
,却没配 JS 切换
类——结果菜单永远藏在那儿,点汉堡图标毫无反应。
更隐蔽的问题是动画:用
切换无法配合
,强行加过渡会失效;而
或
才支持平滑动画。
桌面端用
横向铺开,移动端用
把它设为
(仅隐藏,不移除 DOM)
汉堡按钮必须绑定到一个可被 CSS 选择器监听的状态源,比如
,否则纯 CSS 无法触发显隐
若用 JS 控制,务必监听
和
两个事件,iOS Safari 下单绑
有 300ms 延迟,折叠操作明显卡顿
+
是唯一零 JS 可靠方案
这是目前最稳定、无 JS 降级风险的纯 CSS 实现方式。关键不是“能不能”,而是“为什么必须这样写”:浏览器原生表单控件的状态(如
)能被 CSS 选择器直接捕获,而
或
没有这类状态,CSS 无法监听其变化。
立即学习
“
前端免费学习笔记(深入)
”;
结构上,
必须和目标菜单是兄弟关系(同级),且
在前,菜单在后,才能用
(通用兄弟选择器)精准命中:
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
对应 CSS:
必须放在
前,且
属性与
匹配,确保点击区域 ≥ 44px(iOS 最小触控要求)
别用
,它会导致子元素文字塌陷;
更安全,且支持过渡
如果下拉项动态增减(比如 JS 插入新
),预设的
值可能不够,需 JS 补充计算或改用
替代
用 JavaScript 切换类名时,
比
更可靠
直接操作
会覆盖内联样式、破坏 CSS 过渡,也难维护。现代做法是只管类名,让 CSS 负责表现:
对应 CSS:
用
(如
或
)比缩
或
更安全,避免子项布局挤压、图标错位
移动端要防重复触发:在事件回调里加
,尤其同时监听
和
时
折叠后需手动管理焦点:展开时
到第一个可聚焦项,收起时恢复到触发按钮,否则键盘用户会迷失
侧边栏折叠比顶部导航更麻烦的三个细节
顶部导航折叠只影响高度或横向位移,而侧边栏涉及主内容区重排、滚动行为、固定定位兼容性等连锁反应。
iOS Safari 中
的侧边栏在页面滚动时可能闪动,建议改用
+ 监听
手动更新
主内容区不能只靠
推开侧边栏,响应式下易错位;推荐用
配合
动态分配宽度
折叠状态需持久化:用
存
,刷新后读取并初始化类名,否则用户每次都要重新操作
真正卡住人的从来不是“怎么让菜单动起来”,而是折叠后子菜单的定位偏移、键盘 Tab 顺序断裂、屏幕阅读器播报异常——这些细节漏掉一个,就等于没做完。
navulli:checked@mediadisplay: none.nav-menudisplay: none.nav-menu.active { display: block }activedisplaytransitionmax-heighttransformdisplay: flex@media (max-width: 768px)display: noneclicktouchstartclickinput[type="checkbox"]:checked ~checkeddivbuttoninputinput~
.nav-menu { max-height: 0; overflow: hidden; transition: max-height 0.3s ease; }
#menu-toggle:checked ~ .nav-menu {
max-height: 300px; /* 需略大于所有子项总高,否则动画截断 */
}inputlabelforidheight: 0max-heightlimax-heighttransform: scaleY(0)classList.toggle()style.displayelement.style.display = 'block'document.getElementById('nav-toggle').addEventListener('click', () => {
document.getElementById('nav-menu').classList.toggle('is-open');
});.nav-menu { transition: transform 0.3s ease; }
.nav-menu.is-open { transform: translateY(0); }
.nav-menu:not(.is-open) { transform: translateY(-100%); }transformtranslateYtranslateXwidthheightevent.preventDefault()clicktouchstartfocus()position: fixedposition: absolutescrolltopmargin-leftgrid-template-columnsminmax()localStorage'sidebar-collapsed'