DOCTYPE必须首行无空格,否则IE和旧版Edge进入Quirks Mode导致可访问性语义失效;需配合html5shiv注册HTML5标签、手动设display:block,并确保ARIA属性在标准模式下被识别。

DOCTYPE 必须首行无空格,否则可访问性语义直接失效
很多开发者以为加了 <header> 就算做了可访问性,但 IE 和旧版 Edge 一旦进入 Quirks Mode,不仅布局错乱,role、aria- 属性也会被忽略——屏幕阅读器根本读不到结构信息。
验证方式很简单:打开 Chrome DevTools → Elements 面板顶部看渲染模式,显示 Standards 才算合格;若显示 Quirks,就得立刻检查 HTML 源码开头有没有 BOM、空格或注释。
-
DOCTYPE html>必须独占第一行,前面不能有任何字符(包括 UTF-8 BOM) - 用 VS Code 打开文件时,右下角确认编码是
UTF-8,不是UTF-8 with BOM - PHP 或模板引擎输出前要确保没 echo 空白、没 include 前置空白文件
IE8–10 下 aria-* 属性需配合 html5shiv + display:block 才能被识别
仅引入 html5shiv 不够,它只让 IE 知道 <nav> 是个标签,但不会触发 ARIA 语义解析。更关键的是:这些标签默认是 inline,导致 role="navigation" 被当成无效上下文而丢弃。
必须同时做两件事:
立即学习“前端免费学习笔记(深入)”;
- 条件加载
html5shiv:<!--[if lt IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script><![endif]--> - 手动补全块级样式:
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section { display: block; } - 避免在 IE 中依赖
aria-live或aria-current——它们在 IE10 及以下完全不生效,得用 JS 模拟状态变更并触发focus()
focus() 和 tabindex 在旧浏览器中行为不一致
现代浏览器调用 element.focus() 会自动滚动到可视区域,但 IE8–10 不会,且对 tabindex="-1" 的支持不稳定——有时聚焦失败,有时键盘无法抵达。
安全做法是分层处理:
- 检测是否支持平滑滚动:
if ('scrollIntoView' in element && typeof element.scrollIntoView === 'function'),否则 fallback 到element.scrollIntoViewIfNeeded()(IE10+)或手动计算偏移量 - 设置
tabindex时,优先用0(自然顺序),慎用-1;若必须用-1,确保后续有 JS 主动focus() - IE8 不支持
document.activeElement返回非表单元素,判断焦点位置得靠document.hasFocus()+ 元素级onfocus事件监听
screen reader 对 role 和 landmark 的支持差异极大
不是所有 role 在所有屏幕阅读器中都有效。比如 role="application" 在 JAWS 16+ 和 NVDA 2020+ 支持良好,但在 VoiceOver for iOS 12 之前会被静音;role="feed" 根本没被任何主流阅读器实现过。
实际建议:
- 优先使用原生语义标签:
<nav>比<div role="navigation">更可靠,尤其在 IE + JAWS 组合下 - 避免嵌套 landmark:
<main><section role="region">容易让 NVDA 重复播报,应改用<main><section aria-labelledby="id"> - 动态更新内容时,
aria-live="polite"在 IE11 + JAWS 中延迟明显,需搭配aria-busy="true"+aria-live="off"切换控制节奏
可访问性兼容不是加几个 ARIA 属性就完事的。最常被忽略的是:语义标签必须被浏览器正确解析,而解析前提就是标准模式 + 块级呈现 + 属性存在性验证——三者缺一不可。



















