富文本编辑器输出的HTML默认不可访问,因结构缺失和清洗错误导致屏幕阅读器误读、键盘导航断裂、高对比度失效;需补全lang、title、main三要素,重配DOMPurify放行语义标签,并强制样式隔离。

富文本编辑器输出的 HTML 默认不保证可访问性,直接渲染必然导致屏幕阅读器误读、键盘导航断裂、高对比度模式失效——这不是配置问题,而是结构缺失和清洗策略错误造成的系统性缺陷。
为什么 innerHTML 渲染原始富文本会破坏可访问性
浏览器对 contenteditable 区域的 DOM 生成不可控:quill 可能输出空 <p></p>,CKEditor5 可能插入带 data-mce-* 的残留节点,TinyMCE 甚至保留 Word 复制来的嵌套 <span style="font-family: Calibri">。这些标签在视觉上“看起来正常”,但:
- 空
<p></p>被 NVDA 当作无内容跳过,段落间距却还在,造成语音与视觉错位 -
<img>缺alt或仅写alt="image123.jpg",JAWS 直接播报文件名而非含义 - 用
<div role="button">模拟按钮,但没处理tabindex和Enter/Space响应,键盘用户卡死 -
<table>没role="table"、<th>缺scope,VoiceOver 无法识别行列关系
必须手动补全的三个根级语义结构
别指望浏览器自动补全或编辑器输出完整文档结构。SSR、微前端、iframe 场景下,缺一不可:
-
<html lang="zh-CN">:必须显式声明,否则中文朗读用英文 TTS 引擎,声调全错 -
<title>:不能为空或占位符(如"Untitled"),它是 AT 进入页面后第一个播报内容 -
<main>:全文档只能有一个,且只包裹真正正文(不含 header、sidebar、广告位),否则按 M 键跳转直接失效
注意:<main> 不能嵌套在 <section> 或 <article> 内,否则层级混乱,AT 会降级为普通 div 处理。
立即学习“前端免费学习笔记(深入)”;
清洗 HTML 时 DOMPurify 的关键重配项
DOMPurify.sanitize() 默认白名单会干掉所有语义化标签。必须显式放行并保留关键属性:
- 在
ALLOWED_TAGS中加入:figure、figcaption、aside、section、header、nav - 允许
<img>的alt和loading属性(loading="lazy"对 AT 友好) - 对
<a>至少保留href + title或aria-label,禁止删空链接但允许带说明 - 空
<p></p>不删除,改为<p aria-hidden="true"> </p>(注意中间加一个空格,否则某些 AT 仍忽略)
展示层样式隔离是最后也是最容易被跳过的环节
编辑器输出的 class="mce-item-table" 或内联 style="color:#333" 会覆盖 user agent stylesheet,导致高对比度模式文字消失、焦点框不可见:
- 禁用
v-html或innerHTML直接渲染,必须包裹进独立容器:<div class="rich-content">...</div> - CSS 隔离规则必须写死:
.rich-content * { all: unset; },再显式重置font-size、line-height、color、margin -
<table>强制加role="table",<th>加scope="col"或scope="row" - 所有图标用
<svg>+<title>,或aria-hidden="true"+ 文本替代,禁用 icon font
结构对了、清洗过了、lang 也写了,但没做样式隔离,可访问性就等于零——高对比度用户看到的可能是一片空白或无法聚焦的灰块。



















