<details>不是真正的多标签页,因其无tablist语义、不支持横向排列、方向键切换及aria-controls关联,仅适合单面板手风琴效果。

直接用 <details> + <summary> 就能实现折叠式标签页,但要注意它本质是单面板手风琴(非多标签并存),别误当 Tab 切换用。
为什么<details>不是真正的“多标签页”
<details> 每个实例彼此独立,默认可同时展开多个;但若想模拟「点一个、关其他」的手风琴效果,必须加 JS 控制。它没有内置的 tablist 语义,也不支持横向排列、键盘方向键切换或 aria-controls 关联——这些是 WAI-ARIA 规范里 Tab 标签页(role="tablist")的硬性要求。
常见错误现象:
- 把多个
<details>并排放,以为就是 Tab 标签页,结果用户无法用 Tab 键进入、→/← 切换 - 没加
open属性,首次加载全收起,用户看不到任何内容 - 在 Safari 中只靠
summary::marker改图标,结果箭头不显示或不旋转
想省空间又需多标签并存?用 display 切换 + data-tab 关联
真要实现「多个标签共存、只显一个内容区」,就得放弃 <details>,改用 display: none / display: block 控制显隐,并用 data-tab 明确绑定关系。这是最轻量、可控性最强的方案。
立即学习“前端免费学习笔记(深入)”;
实操要点:
- 所有面板提前写死在 HTML 中,不要动态插入——避免 SSR 不一致和焦点丢失
- 每个页签按钮加
role="tab"、tabindex="0",当前激活项设tabindex="-1" - 对应面板加
role="tabpanel"和aria-labelledby,指向页签的id - 用
click+keydown(监听 Enter / Space)双触发,保障键盘可用 - 首次加载时手动调用一次切换逻辑,确保默认面板可见
含 iframe / video / 表单的标签页,别用 display: none
如果某个标签页里嵌了 <iframe> 或正在播放的 <video>,用 display: none 会强制暂停、清空状态、丢失表单输入值。这时候该换方案:
- 改用
visibility: hidden+position: absolute+left: -9999px移出视口,保留渲染上下文 - 同步更新
aria-hidden="true",否则屏幕阅读器仍会读取隐藏内容 - 切换时手动聚焦到新面板首个可聚焦元素(如第一个
<input>),避免键盘导航断连 - 慎用
opacity: 0—— 它不阻止交互,用户可能误点不可见区域
需要滑动动画?max-height + scrollHeight 是唯一靠谱路径
<details> 不支持高度过渡;display 切换也没动画。真要滑动展开,只能靠 max-height + JS 动态读取 scrollHeight:
- 初始设
max-height: 0+overflow: hidden - 展开时先设
max-height: 0,强制重排,再设为element.scrollHeight + 'px' - 收起后务必清空
style.maxHeight(设为''),否则下次scrollHeight可能读错 - 别写死
max-height: 500px—— 内容短时会“弹跳”,长时又切不全
这个过程看似简单,但 scrollHeight 在字体加载未完成、图片未解码时可能不准,实际项目中建议加 fontLoad 或 img.onload 后再测高。



















