纯 CSS 响应式标签页应优先使用 <details><summary>,因其原生支持键盘操作、无障碍语义完整且兼容 iOS Safari;若用 radio 模拟,须确保唯一 ID 关联、正确隐藏输入框、用属性选择器控制显隐,并始终设置 aria-hidden 和 tabindex;禁用 touch 滑动,强制依赖点击/Enter/Space 切换。

纯 CSS 实现的 HTML 响应式标签页,能跨设备工作,但默认不兼容键盘和屏幕阅读器——必须补全可访问性链路,否则在 iOS Safari 或 NVDA 下会完全失效。
用 <details><summary> 实现最简响应式标签页
这是唯一无需 JS、原生支持键盘(Enter/Space)、自带 open 属性、且在所有现代浏览器(含 iOS Safari 12.2+)中稳定工作的方案。
-
<summary>必须是<details>的第一个子元素,否则语义断裂,屏幕阅读器无法识别“控制-内容”关系 - 默认箭头样式不可靠,用
summary::marker { content: "▶"; }替代 JS 切 class,更轻量也更可控 - 必须保留
summary:focus { outline: 2px solid #007aff; },这是键盘用户唯一可依赖的焦点反馈 - 若需多组独立标签页,每组用独立
<details>,不要嵌套或复用同一个open状态
用 <input type="radio"> + CSS 模拟标签页时的关键陷阱
它看似灵活,但极易在可访问性和状态同步上翻车,尤其在 SSR 或 JS 失效场景下。
- 每个
<input>必须有唯一id,且对应<label for="xxx">和目标面板的id,缺一不可 - 隐藏复选框不能用
display: none或visibility: hidden,必须用position: absolute; opacity: 0; pointer-events: none,否则脱离可访问树 - 显隐逻辑必须用
input:checked ~ .tab-panel[id="panel-1"]这类属性选择器驱动,而非兄弟序号选择器(如input:checked + .tab-panel),避免 DOM 顺序微调就崩 - 激活面板必须同时设
aria-hidden="false"和tabindex="0",否则键盘用户无法聚焦内容区
移动端要不要加 touch 手势滑动切换?
不要。原生 touchstart/move/end 手势模拟标签页滑动,会与 iOS Safari 的页面回退手势冲突,极易触发“误拖拽退出当前页”,且无法被 preventDefault() 完全拦截(截至 2026 年 5 月)。
立即学习“前端免费学习笔记(深入)”;
- 所有切换行为应严格绑定到点击/空格/Enter,保持与
<details>或<input type="radio">原生语义一致 - 若真需滑动体验,应在服务端或构建时生成独立页面,用路由跳转替代 DOM 切换,避开手势劫持问题
- CSS
scroll-snap-type不适用于标签页切换——它只对容器内滚动生效,无法触发面板显隐
最常被忽略的一点:无论用哪种方案,<meta name="viewport" content="width=device-width, initial-scale=1.0"> 必须存在且位于 <head> 最前面。没有它,iOS Safari 会强制以 980px 宽度渲染,导致标签页控件被缩成针尖大小,连点击都困难。



















