响应式布局本身不提升可访问性,反而常因结构错乱加剧障碍;必须用语义标签锚定DOM层级,并同步维护焦点流与ARIA状态。

响应式布局本身不提升可访问性,反而常因结构错乱加剧障碍;必须用语义标签锚定 DOM 层级,并同步维护焦点流与 ARIA 状态。
为什么不能嵌套在或
浏览器和屏幕阅读器(如 NVDA、VoiceOver)把 <main></main> 当作唯一主内容入口点。一旦它被包进 <header></header> 或 <nav></nav>,语义层级就塌了——键盘 Tab 流会跳过整个 <main></main>,读屏软件可能直接忽略它,或误判为辅助区域。
- 每个页面只允许一个
<main></main>;重复出现时,W3C 验证报错,NVDA 2025+ 会静默丢弃第二个 -
<main></main>必须是的直接子元素,不能藏在<div class="wrapper"> 或 JS 动态插入的容器里 <li>移动端用 JS 把桌面端的 <code><main></main>移动到 off-canvas 内部?立刻失效——必须重写 DOM 结构,而非仅改 CSS - 触发按钮必须是原生
<button></button>或带role="button"的<label></label>,且绑定input[type="checkbox"]—— 否则无 JS 时不可操作 - 展开后的菜单项(
<a></a>或<button></button>)要天然可聚焦;别用tabindex="-1"锁死,也别靠 JS 模拟 click - 菜单打开后,焦点必须立即
focus()到第一个可操作项;关闭后,焦点必须回到触发按钮 - 禁用
display: none控制显隐——它让元素彻底退出焦点流;改用visibility: hidden+aria-hidden="true" - 不要用 JS 删除/重建整张表;优先用 CSS Grid +
sr-only类隐藏列,保留原始<th scope="col"> 结构 <li>若必须 JS 生成卡片,每个卡片内需手动补全 <code>aria-labelledby="q3-label",指向对应标题的 ID - 单选/复选框组必须用
<fieldset></fieldset>+<legend></legend>包裹,不能靠视觉缩进模拟层级 - 动态加载新卡片时,包裹容器要设
aria-live="polite",否则 VoiceOver 不播报新增项 - 所有可交互元素(
<button></button>、<a></a>、<input>)最小尺寸必须 ≥ 44×44px,用padding扩展点击区,别只调font-size - 焦点状态不能只靠颜色变化;必须有明确轮廓,例如
outline: 2px solid #0066cc,且支持:focus-visible区分鼠标/键盘触发 - 禁用
user-select: none在按钮或链接上——TalkBack 会因此无法识别长按操作 -
lang="zh-CN"必须写在标签上,否则 NVDA 读中文会卡顿或切英文音库
汉堡菜单展开后键盘焦点去哪儿了
响应式导航最常卡死的地方:菜单一展开,Tab 键就“掉线”。这不是样式问题,是交互流断裂。
响应式表格/卡片流怎么保持语义连贯
移动端把 <table> 拆成垂直卡片流很常见,但若只靠 CSS 隐藏列、JS 重排 DOM,<code>scope="col" 和 aria-labelledby 关系就断了,屏幕阅读器无法把“选项A”和“问题3”关联起来。
立即学习“前端免费学习笔记(深入)”;
触控目标和视觉焦点反馈怎么达标
移动端可访问性的硬门槛不是“看起来像按钮”,而是手指能稳稳点中、键盘能清晰跳转、语音能准确定位。
真正难的不是加几个 aria- 属性,而是每次改布局前先问一句:这个改动会不会让 DOM 顺序和语义层级“脱钩”?一旦视觉折叠和语义结构不同步,无障碍就从起点开始失效。



















