用 hidden 属性 + CSS 类控制显隐更可靠易维护,天然支持无障碍和动画;data-tab 关联比 id 更安全;需完善键盘导航(Tab/方向键/Enter/Space)及 ARIA 语义。

用 hidden 属性 + CSS 类控制显隐,比直接操作 style.display 更可靠、更易维护,也天然支持无障碍和动画。
为什么不用 display: none 直接写在 JS 里?
硬编码 style.display = 'none' 会让样式逻辑和行为逻辑耦合,后续加淡入、响应式隐藏或 SSR 支持时就得反复改 JS;还容易漏掉重置——比如切换前没统一隐藏所有面板,旧内容残留;或者目标元素不存在时,targetEl.style.display = 'block' 报错中断脚本。
- 用
hidden属性语义明确:HTML 原生支持,[hidden] { display: none; }可全局统一控制 - CSS 中定义
.tab-pane:not([hidden]) { opacity: 1; transition: opacity 0.2s; },JS 只管开关hidden,职责清晰 - 服务端渲染(SSR)时可预设
hidden,客户端 JS 激活后只需移除它,避免闪屏
data-tab 关联比 id + getElementById 更安全
用 id 匹配面板要求全局唯一,但组件复用时极易冲突(比如两个 Tab 组件都含 id="tab1");data-tab 是局部作用域的键,配合 aria-controls 还能保障无障碍。
- 标签按钮写
- 面板写 ...
- JS 中用
document.querySelector(`[id="${btn.dataset.tab}"]`)不如用document.getElementById(btn.getAttribute('aria-controls'))稳定——因为aria-controls明确指向目标 ID,且不依赖驼峰转换规则
键盘导航不能只靠鼠标点击
仅绑定 click 事件,Tab 键用户根本进不到标签项,方向键也无法切换——这在 WCAG 2.1 中属于严重可访问性缺陷。
- 每个标签按钮必须有
tabindex="0",且激活态设aria-selected="true" - 监听
keydown,对ArrowLeft/ArrowRight找相邻兄弟节点并focus(),同时更新aria-selected - 按
Enter或Space时触发click,复用已有逻辑,不重复写切换代码 - 别忘了给外层容器加
role="tablist",这是屏幕阅读器识别标签组的前提
最简健壮的切换核心就三步:统一移除所有面板的 hidden,给目标面板删掉 hidden,同步更新按钮的 aria-selected 和焦点。其余都是围绕这三步补全语义、动画和键盘支持——漏掉任何一环,都可能在某个浏览器、某类用户或某种加载条件下出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











