AI应用的可访问性设计:让产品惠及更多人
AI应用的可访问性设计:让产品惠及更多人
前言
我们的产品上线后,收到了视障用户的反馈:"你们的应用很好,但对我来说完全没法用。"
那一刻我意识到:可访问性不是锦上添花,而是产品设计的基本要求。
今天,分享我们是如何改进产品可访问性的。
一、可访问性基础
1.1 什么是可访问性
可访问性(Accessibility)确保产品能被尽可能多的人使用,包括残障人士。
1.2 残障类型与影响
| 类型 | 影响 | 设计考虑 |
|---|---|---|
| 视觉障碍 | 无法看见屏幕 | 屏幕阅读器、颜色对比度 |
| 听觉障碍 | 无法听见声音 | 字幕、手语、视频文字 |
| 运动障碍 | 操作困难 | 键盘导航、语音控制 |
| 认知障碍 | 理解困难 | 清晰语言、可预测设计 |
二、界面可访问性
2.1 语义化 HTML
# Jinja2 模板示例 ACCESSIBLE_TEMPLATE = """ <!-- 不推荐 --> <div class="button" onclick="submit()">提交</div> <!-- 推荐 --> <button type="submit" aria-label="提交表单">提交</button> <!-- 不推荐 --> <div class="modal"> <div class="close">X</div> </div> <!-- 推荐 --> <div role="dialog" aria-modal="true" aria-labelledby="modal-title"> <button class="close" aria-label="关闭">X</button> </div> """2.2 ARIA 属性
ARIA_EXAMPLES = { "button_with_loading": ''' <button aria-busy="true" aria-label="提交中,请稍候"> 提交 </button> ''', "form_error": ''' <input type="text" aria-invalid="true" aria-describedby="email-error" /> <span id="email-error" role="alert"> 请输入有效的邮箱地址 </span> ''', "live_region": ''' <div aria-live="polite" aria-atomic="true"> {{ status_message }} </div> ''' }三、AI 交互可访问性
3.1 语音交互
class VoiceInterface: def __init__(self): self.supported_commands = {} def add_command(self, phrase: str, action: str, description: str): """添加语音命令""" self.supported_commands[phrase] = { "action": action, "description": description } def speak(self, text: str, priority: str = "medium"): """语音播报""" if priority == "high": self._announce_immediately(text) else: self._queue_for_speech(text) def _announce_immediately(self, text: str): """立即播报""" # 使用 Web Speech API return f'<script>speechSynthesis.speak(new SpeechSynthesisUtterance("{text}"))</script>'3.2 屏幕阅读器适配
class ScreenReaderSupport: def generate_description(self, element_type: str, content: dict) -> str: """生成屏幕阅读器描述""" descriptions = { "chat_message": f"用户 {content['user']} 说:{content['message']}", "ai_response": f"AI 助手回答:{content['response']}", "loading": "正在加载,请稍候", "error": f"错误:{content['message']}" } return descriptions.get(element_type, "") def format_list(self, items: list) -> str: """格式化列表供屏幕阅读器""" if not items: return "列表为空" formatted = [] for i, item in enumerate(items, 1): formatted.append(f"{i},{item}") return ",".join(formatted)四、设计原则
4.1 颜色对比度
class ColorContrastChecker: def check_contrast(self, foreground: str, background: str) -> dict: """检查颜色对比度""" fg_luminance = self._get_luminance(foreground) bg_luminance = self._get_luminance(background) ratio = self._calculate_ratio(fg_luminance, bg_luminance) return { "ratio": f"{ratio:.2f}:1", "passes_aa": ratio >= 4.5, # 普通文本 "passes_aaa": ratio >= 7.0, # 增强文本 "recommendation": "通过" if ratio >= 4.5 else "需要提高对比度" }4.2 键盘导航
class KeyboardNavigation: def get_focus_order(self, page_elements: list) -> list: """计算焦点顺序""" return sorted( page_elements, key=lambda e: (e.get("tab_order", 0), e.get("position_y", 0)) ) def add_shortcuts(self, shortcuts: dict) -> str: """生成快捷键说明""" html = '<div class="keyboard-shortcuts" aria-label="快捷键">' html += '<h3>键盘快捷键</h3><ul>' for key, description in shortcuts.items(): html += f'<li><kbd>{key}</kbd>: {description}</li>' html += '</ul></div>' return html五、测试与验证
5.1 自动化测试
class AccessibilityTest: def run_axe_test(self, page_html: str) -> dict: """运行 axe 自动化测试""" # 模拟 axe-core 结果 return { "violations": [ { "id": "color-contrast", "impact": "serious", "description": "文本与背景颜色对比度不足", "nodes": ["#header", "#button-primary"] }, { "id": "button-name", "impact": "critical", "description": "按钮没有可访问名称", "nodes": ["#submit-btn"] } ], "passes": 45 }5.2 手动测试清单
ACCESSIBILITY_CHECKLIST = [ "所有图片都有 alt 文本", "表单有正确的 label 关联", "颜色对比度符合 WCAG AA 标准", "支持完整的键盘导航", "所有交互都有焦点指示", "错误消息使用 aria-describedby 关联", "页面有清晰的标题结构", "动态内容使用 aria-live 通知" ]六、最佳实践
6.1 开发原则
- ✅语义化优先:用正确的 HTML 元素
- ✅渐进增强:先保证基本功能
- ✅测试友好:便于自动化测试
- ✅持续关注:把可访问性纳入开发流程
6.2 AI 特有考虑
- ✅多模态输出:支持语音、视觉、文字
- ✅清晰语言:避免技术术语
- ✅即时反馈:操作结果立即告知
- ✅可中断性:用户可随时停止
七、总结
可访问性让产品惠及更多人。关键在于:
- 意识先行:理解可访问性的重要性
- 设计融入:从设计阶段就考虑
- 技术实现:用正确的技术方法
- 持续测试:不断验证和改进
记住:好的设计对每个人都友好。
