LWC开发者必备:编码阶段无障碍(a11y)快速自查清单
14
0
0
0
LWC 无障碍(a11y)快速自查表
1. 表单元素缺少标签 (Missing Input Labels)
2. 交互元素键盘不可操作 (Keyboard Operability)
3. 焦点丢失或管理混乱 (Focus Management)
4. 颜色对比度不足 (Insufficient Color Contrast)
5. 滥用 div 或 span 做按钮 (Semantic HTML for Buttons)
6. 图像缺少替代文本 (Missing Image Alt Text)
7. 缺乏清晰的焦点指示 (Missing Visual Focus Indicator)
8. 标题层级结构不当 (Improper Heading Structure)
养成习惯,防患未然
嘿,各位LWC开发者!还在等QA或专门的a11y测试才发现那些恼人的无障碍问题吗?别傻了!很多常见的a11y错误完全可以在编码阶段就轻松搞定。早发现、早修复,不仅省时省力,更能让你的组件从一开始就具备良好的可访问性,对用户(尤其是依赖辅助技术的用户)更友好。
这不仅仅是“政治正确”或者满足合规要求,这是专业素养的体现,更能扩大你产品的用户群。想想看,键盘党、视障用户、甚至临时不方便用鼠标的人,都能流畅使用你的功能,这难道不酷吗?
这份清单专为忙碌的你设计,聚焦几个最常见、影响最大的问题。把它当作你的编码“随身听”,随时对照检查,养成习惯。
LWC 无障碍(a11y)快速自查表
1. 表单元素缺少标签 (Missing Input Labels)
- 为啥重要? 屏幕阅读器用户不知道输入框是干嘛的。想象一下,只听到“输入框”,让你填啥?姓名?邮箱?密码?鬼知道!
- 咋快速检查?
- 看看你的
<lightning-input>
,<lightning-combobox>
,<lightning-textarea>
,<lightning-checkbox>
,<lightning-radio-group>
等组件,是不是都设置了label
属性? - 如果 label 在视觉上隐藏了(比如用了
label-hidden
变体),确保label
属性 仍然 存在,它对屏幕阅读器至关重要。 - 对于完全自定义的输入控件,确保有关联的
<label>
元素,或者使用了aria-label
/aria-labelledby
。
- 看看你的
- 咋修复?
- 首选: 给所有
lightning-*
输入组件加上明确的label
属性。例如:<lightning-input label="电子邮件" type="email"></lightning-input>
。 - 如果视觉上不需要标签,但语义上需要:
<lightning-input label="搜索" variant="label-hidden" type="search"></lightning-input>
。 - 自定义控件:使用
<label for="inputId">标签文本</label>
并确保 input 有对应的id="inputId"
,或者直接在 input 上加aria-label="描述性标签"
。
- 首选: 给所有
2. 交互元素键盘不可操作 (Keyboard Operability)
- 为啥重要? 很多用户只用键盘导航(比如我,敲代码时懒得碰鼠标),或者因为身体原因必须用键盘。如果你的按钮、链接、自定义菜单只能用鼠标点,他们就被拒之门外了。
- 咋快速检查?
- 丢掉鼠标,只用
Tab
键(前进)和Shift + Tab
(后退)试试能不能选中你组件里 所有 的交互元素(按钮、链接、自定义下拉菜单触发器等)。 - 选中后,试试用
Enter
或Space
键能不能触发它们的功能(比如点击按钮、打开菜单)。
- 丢掉鼠标,只用
- 咋修复?
- 标准元素优先: 尽可能使用原生的
<button>
,<a>
或对应的lightning-button
,lightning-button-menu
等。它们天生支持键盘操作。 - 避免滥用
div
/span
: 不要用div
或span
加个onclick
事件就当作按钮!这绝对是新手最容易犯的错误之一。 - 如果必须用非语义化标签(非常不推荐):
- 给它加上
tabindex="0"
让它能被 Tab 键聚焦。 - 添加
role="button"
(或其他合适的 ARIA role)。 - 必须 添加键盘事件监听器,响应
Enter
和Space
键(通常和click
事件触发相同的逻辑)。例如,在 LWC 的 JS 里:
然后在模板里:handleKeydown(event) { if (event.key === 'Enter' || event.key === ' ') { this.handleClick(); // 调用你原本的点击处理逻辑 } } <div class="custom-button" tabindex="0" role="button" onclick={handleClick} onkeydown={handleKeydown}>点击我</div>
- 给它加上
- 标准元素优先: 尽可能使用原生的
3. 焦点丢失或管理混乱 (Focus Management)
- 为啥重要? 操作后(比如打开/关闭模态框、动态加载内容),键盘焦点应该移动到合乎逻辑的位置。如果焦点丢失(回到
<body>
)或跳到奇怪的地方,键盘用户会一脸懵逼,不知道当前在哪,接下来该干嘛。 - 咋快速检查?
- 执行那些会改变 UI 状态的操作(打开对话框、显示/隐藏区域、异步加载数据后出现新内容)。
- 操作完成后,按一下
Tab
键,看看焦点现在在哪里?它是否在:- 新出现的容器/模态框的第一个可聚焦元素上?
- 触发操作的元素之后(如果没出现新容器)?
- 或者至少在可预测、合理的位置?
- 关闭模态框或折叠区域后,焦点是否返回到触发它的那个元素上?
- 咋修复?
- 手动设置焦点: 在 LWC 的 JS 中,使用
this.template.querySelector('选择器').focus()
来显式设置焦点。// 模态框打开后,聚焦到内部的第一个输入框 async handleOpenModal() { this.showModal = true; // 需要等待 DOM 更新完成 await Promise.resolve(); // 或者使用 requestAnimationFrame const firstInput = this.template.querySelector('lightning-input'); if (firstInput) { firstInput.focus(); } } // 模态框关闭后,焦点返回触发按钮 handleCloseModal() { this.showModal = false; const triggerButton = this.template.querySelector('.trigger-button-class'); // 假设触发按钮有个类名 if (triggerButton) { triggerButton.focus(); } } - 模态框/对话框焦点陷阱: 对于模态框 (
lightning-modal
或自定义),确保用户Tab
键焦点被限制在模态框内部,不会跑到后面的页面内容去。lightning-modal
自带部分焦点管理,但复杂场景可能需要手动增强。
- 手动设置焦点: 在 LWC 的 JS 中,使用
4. 颜色对比度不足 (Insufficient Color Contrast)
- 为啥重要? 文字和背景颜色对比度太低,视力不佳的用户(包括色弱、老年人,甚至在强光下看屏幕的普通人)会看不清内容。
- 咋快速检查?
- 浏览器开发者工具: 选中元素,在
Styles
或Computed
面板里找到color
和background-color
。很多浏览器(如 Chrome, Firefox, Edge)会直接显示对比度数值,并告诉你是否符合 WCAG AA (4.5:1 普通文本 / 3:1 大文本) 或 AAA 标准。 - 使用在线工具或浏览器插件: 搜索 “Color Contrast Checker” 或安装类似 axe DevTools、WAVE 等插件,它们能自动检测对比度问题。
- 特别留意:灰色的文字、背景上的文字、按钮文字、状态颜色、自定义图表颜色。
- 浏览器开发者工具: 选中元素,在
- 咋修复?
- 调整颜色: 修改 CSS,选择对比度更高的颜色组合。优先使用 Salesforce Lightning Design System (SLDS) 提供的设计 token(Design Tokens),它们通常考虑了无障碍性。
- 遵循标准: 目标至少是 WCAG 2.1 AA 级别。普通大小文本(小于 18pt 或 14pt bold)对比度 >= 4.5:1,大文本(>= 18pt 或 14pt bold)对比度 >= 3:1。
- 别只依赖颜色: 不要仅通过颜色来传达信息(如图标状态),应同时提供文本标签、形状变化或其他视觉提示。
5. 滥用 div
或 span
做按钮 (Semantic HTML for Buttons)
- 为啥重要? 这和第 2 点“键盘不可操作”高度相关,但更侧重于“语义”。屏幕阅读器无法识别一个
<div>
是按钮,即使用户能用鼠标点击它。它缺少按钮的角色(role)、状态(如aria-pressed
)等重要信息。 - 咋快速检查?
- 右键点击你看起来像按钮的东西,选择“检查”或“审查元素”。看看它在 DOM 里到底是
<button>
、<a>
还是<div class="looks-like-a-button">
? - 特别是那些用 SLDS 的
slds-button
CSS 类但套在div
或span
上的情况。
- 右键点击你看起来像按钮的东西,选择“检查”或“审查元素”。看看它在 DOM 里到底是
- 咋修复?
- 用对标签: 如果它执行一个动作,用
<button>
或<lightning-button>
。如果它导航到一个新页面/视图,用<a>
(配合href
或 LWC 路由)。 - SLDS 配合语义标签: SLDS 的样式类应该应用在正确的 HTML 元素上。
<button class="slds-button slds-button_brand">Brand Button</button>
是正确的,<div class="slds-button slds-button_brand">Not a Button</div>
是错误的。 - 特殊情况(极少): 如果你真的、真的、真的因为某种复杂布局或组件库限制,不得不基于
div
构建交互元素,那么除了tabindex="0"
和键盘事件处理(见第 2 点),还必须加上role="button"
,并且可能需要用aria-pressed
等 ARIA 属性来管理状态。
- 用对标签: 如果它执行一个动作,用
6. 图像缺少替代文本 (Missing Image Alt Text)
- 为啥重要? 屏幕阅读器用户无法“看到”图片,替代文本(Alt Text)是他们理解图片内容的唯一途径。搜索引擎也用它来理解图片。
- 咋快速检查?
- 检查你模板里所有的
<img>
标签,有没有alt
属性?它的值有意义吗? - 检查
<lightning-icon>
,有没有设置alternative-text
属性? - 检查
<lightning-avatar>
,alternative-text
是否合适? - 背景图片(CSS
background-image
)通常是装饰性的,但如果它传递重要信息,需要用其他方式(如旁边的文字)提供。
- 检查你模板里所有的
- 咋修复?
- 提供描述性
alt
/alternative-text
: 如果图片传递信息,用简洁的语言描述图片内容或功能。例如<img src="user_avatar.jpg" alt="张三的头像">
,<lightning-icon icon-name="utility:warning" alternative-text="警告"></lightning-icon>
。 - 装饰性图片: 如果图片纯粹是装饰,没有实际信息量(比如分隔线、背景纹理),提供一个空的
alt
属性 (alt=""
)。这告诉屏幕阅读器忽略它,而不是读出文件名。 - 图标按钮: 如果一个图标本身就是按钮(比如只有图标的删除按钮),
alternative-text
应该描述按钮的功能,例如<lightning-button-icon icon-name="utility:delete" alternative-text="删除条目"></lightning-button-icon>
。
- 提供描述性
7. 缺乏清晰的焦点指示 (Missing Visual Focus Indicator)
- 为啥重要? 键盘用户需要明确知道当前哪个元素获得了焦点,否则就像在黑暗中摸索。默认的浏览器或 SLDS 通常会提供焦点轮廓(通常是蓝色或黑色的框),但有时会被自定义 CSS 意外覆盖掉。
- 咋快速检查?
- 只用
Tab
键在你的组件内导航。每按一次 Tab,是否能清楚地看到哪个元素被选中了?(注意看是否有边框、轮廓、背景色变化等)。 - 特别检查自定义控件、或者样式被深度定制的标准控件。
- 只用
- 咋修复?
- 不要禁用默认焦点样式: 避免使用
outline: none;
或outline: 0;
来全局或针对性地移除焦点指示器,这是最常见的错误! - 确保 SLDS 样式正确应用: 如果使用 SLDS,确保其焦点样式(通常是蓝色的外框
box-shadow
)没有被你的自定义 CSS 覆盖。 - 自定义焦点样式: 如果你必须自定义焦点样式(比如为了品牌一致性),确保新的样式足够明显、对比度高,并且在不同背景下都清晰可见。可以使用
:focus
和:focus-visible
伪类来定义。/* 示例:自定义一个红色虚线焦点框 */ .my-custom-element:focus-visible { outline: 2px dashed red; outline-offset: 2px; /* 让轮廓稍微离开元素一点,避免遮挡 */ }
- 不要禁用默认焦点样式: 避免使用
8. 标题层级结构不当 (Improper Heading Structure)
- 为啥重要? 屏幕阅读器用户经常使用标题(
h1
到h6
)来快速浏览和理解页面结构,就像视力正常用户扫读标题一样。如果标题层级混乱(比如从h2
直接跳到h4
,中间没有h3
),会破坏这种导航体验,让页面结构难以理解。 - 咋快速检查?
- 使用浏览器开发者工具检查 DOM 结构,看看页面/组件中的
h1
,h2
,h3
... 标签是否按逻辑层级排列? - 使用 a11y 检查插件(如 WAVE, axe DevTools),它们通常会高亮显示标题结构问题。
- 简单来说:页面主标题是
h1
(通常 SLDS 应用级别会处理好),你的组件内部的章节标题应该是h2
,子章节是h3
,以此类推。不要跳级!
- 使用浏览器开发者工具检查 DOM 结构,看看页面/组件中的
- 咋修复?
- 按顺序使用标题: 遵循
h1
->h2
->h3
->h4
... 的层级结构。在一个h2
下面应该是h3
,而不是直接出现h4
。 - 使用 SLDS Heading Blueprint: 如果需要特定样式的标题,优先使用 SLDS 提供的标题样式类(如
slds-text-heading_large
),但将它们应用在正确的h
标签上,而不是用div
或span
伪装成标题。 - 区分样式和语义: 不要因为某个级别的标题看起来太大或太小就跳级。标题的级别(
h1
-h6
)定义的是结构,外观应该由 CSS 控制。如果需要h3
的结构但想要h2
的外观,那就用<h3 class="slds-text-heading_medium">
(假设slds-text-heading_medium
对应 H2 的视觉样式)。
- 按顺序使用标题: 遵循
养成习惯,防患未然
这份清单不可能涵盖所有 a11y 问题,但它能帮你快速捕捉到那些最容易犯、影响也最大的错误。
关键在于:
- 编码时就想着 a11y: 别等写完了再“补票”。选对 HTML 元素、用好 LWC 内置属性、遵循 SLDS 指南,能省去很多麻烦。
- 随时自测: 写完一小块功能,就花几秒钟用 Tab 键走一遍,看看关键元素有没有标签,颜色对比度大概如何。
- 利用工具: 浏览器开发者工具、axe DevTools、WAVE 等插件都是你的好帮手,可以在开发过程中实时检查。
记住,无障碍不是一项额外任务,而是高质量软件开发的内在组成部分。从现在开始,让这个快速清单成为你 LWC 开发工具箱里的一部分吧!你的用户会感谢你的!