应使用 radio + :checked + CSS 实现标签页,details 仅适用于面板内局部折叠;复杂联动和焦点管理需 JS 支持。

用 details 做标签页?别硬套,语义和行为都不对
HTML 的 details 是为「单个可展开/收起内容块」设计的,不是标签页(tabs)的替代品。标签页核心是「互斥切换」+「状态持久可见」+「焦点可导航」,而 details 默认各自独立、无状态联动、标题不可聚焦到非激活项。强行用多个 details 模拟 tabs,会破坏键盘操作逻辑(比如 Tab 键无法在 tab 标题间跳转)、屏幕阅读器识别混乱,且 Safari 下嵌套或联动时容易失效。
原生方案:用 radio + :checked + CSS 实现真标签页
这是目前最轻量、零 JS、语义合理、无障碍友好的纯 HTML/CSS 标签页方案,同时天然支持折叠逻辑(每个 tab 面板可独立收起)。
-
input[type="radio"]控制唯一选中状态,name 相同即自动互斥 -
label[for]作为 tab 标题,点击即选中对应 radio - 用
~或+选择器控制对应面板的max-height和opacity - 默认隐藏所有面板,仅当前选中项展开:
input:checked ~ .panel { max-height: 300px; opacity: 1; } - 加
transition: max-height 0.25s ease, opacity 0.2s实现平滑过渡
混合需求:标签页内嵌折叠面板,直接用 details 即可
如果只是「每个 tab 面板内部需要局部折叠」,那完全没问题——details 就是干这个的。只要确保它只出现在 tab 内容区里,不参与 tab 切换逻辑。
- tab 面板本身由 radio 控制显隐,内部结构自由:
小标题
可折叠内容
Convert Markdown To HTML And PDF - Markdown和HTML、PDF互转下载实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
- 注意:不要把
details放在 radio 标签外层,否则可能干扰 :checked 选择器范围 - Safari 对
details的::marker渲染不稳定,统一用summary::before补图标更可靠 - 避免给
details设height或display过渡——它不支持,动画必须靠父级 panel 的max-height控制
要手风琴(accordion)+ 标签页联动?JS 不可避免
当需求变成「点一个 tab,自动展开该 tab 下第一个 details,同时收起其他 tab 里的所有 details」,纯 CSS 已无法满足。因为 CSS 无法跨兄弟元素监听状态变化,也做不到「选中 radio → 触发某个 details.open = true」。
- 监听
input[type="radio"]的change事件 - 先遍历所有
details,设el.open = false - 再根据当前 radio 的
value或data-target找到对应 tab 区域,查其内部第一个details并设open = true - 注意:直接赋值
open不触发toggle事件,所以状态同步得自己维护,别依赖事件回调来更新 UI
真正容易被忽略的是焦点管理:用户用键盘切换 tab 后,焦点应自动落到该 tab 面板的第一个可聚焦元素(比如内部 details > summary),否则不符合 WCAG 2.1 标准。这点纯 CSS 方案完全做不到,必须 JS 补全。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










