将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
表单无障碍需语义结构、焦点流、动态反馈三者闭环;label与input须for/id严格匹配;错误提示须预置dom、用textcontent更新、配aria-invalid与aria-describedby;动态播报要节流清空并兼容旧版safari。

表单无障碍不是加几个 ARIA 属性就完事,核心是语义结构 + 焦点流 + 动态反馈三者闭环。漏掉任意一环,屏幕阅读器用户大概率卡在输入框里读不到错误、点不了提交、甚至不知道当前字段叫什么。
label 和 input 必须显式关联,for/id 严格匹配
这是最基础也最容易翻车的一环。屏幕阅读器不认视觉位置、不认包裹结构、不认 placeholder,只认 for 和 id 的字面完全一致。
-
for值必须和input的id逐字符相等:大小写、连字符、下划线、首尾空格都不能差——比如for="user-name"对应id="user-name",写成id="username"或id=" User-name "都会断开 - 禁用隐式包裹:
<label>邮箱<input id="email"></label>看似方便,但中间插入注释、换行或 JS 动态节点后,关联立即失效 - select 下拉框更敏感:iOS VoiceOver 要求
label和select在 DOM 中紧邻,中间插个<p></p>就可能点 label 文本无法聚焦
错误提示必须预置 DOM、用 textContent 更新、配对 aria-invalid + aria-describedby
常见现象是 JS 插入错误 div 后,NVDA 或 VoiceOver 完全没反应——问题不在 aria-live,而在错误元素根本没进可访问性树。
- 错误容器(如
<div id="email-error"></div>)必须在页面加载时就存在于 DOM 中,哪怕内容为空;不能靠document.createElement+appendChild临时创建 - 更新错误文案必须用
textContent,严禁innerHTML = error.message(XSS 风险 + 可访问性树不触发更新) -
aria-invalid="true"单独存在毫无意义,它只是状态标记;必须配合aria-describedby="email-error"才能把错误文本和输入框真正绑定 - 多个错误共用一个 input 时,
aria-describedby值用空格分隔:aria-describedby="email-error email-format-error"
动态错误播报要节流、清空、降级兼容旧浏览器
频繁写入 aria-live 区域会导致 iOS VoiceOver 卡顿、NVDA 漏播,而 Safari 15 以下甚至需要手动重设属性才能触发。
- 写入前先清空上一条:
liveRegion.textContent = '',再赋新值,避免残留文本干扰播报节奏 - 实时校验场景必须加节流(如 300ms),否则用户每敲一个键都报错,体验灾难
- 旧版 Safari 需额外处理:插入错误后立即执行
liveRegion.setAttribute('aria-live', 'polite'),部分版本不重设就不播报 - 严重错误(如网络失败)可用
aria-live="assertive",但它会中断当前播报,慎用
最常被忽略的其实是「错误摘要」:表单顶部没聚合错误列表、没提供跳转链接,用户得一个个 tab 过去听,效率极低。这比单个字段的 ARIA 配置更影响实际使用路径。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










