WEBKT

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 (后退)试试能不能选中你组件里 所有 的交互元素(按钮、链接、自定义下拉菜单触发器等)。
    • 选中后,试试用 EnterSpace 键能不能触发它们的功能(比如点击按钮、打开菜单)。
  • 咋修复?
    • 标准元素优先: 尽可能使用原生的 <button>, <a> 或对应的 lightning-button, lightning-button-menu 等。它们天生支持键盘操作。
    • 避免滥用 div / span 不要用 divspan 加个 onclick 事件就当作按钮!这绝对是新手最容易犯的错误之一。
    • 如果必须用非语义化标签(非常不推荐):
      • 给它加上 tabindex="0" 让它能被 Tab 键聚焦。
      • 添加 role="button" (或其他合适的 ARIA role)。
      • 必须 添加键盘事件监听器,响应 EnterSpace 键(通常和 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 自带部分焦点管理,但复杂场景可能需要手动增强。

4. 颜色对比度不足 (Insufficient Color Contrast)

  • 为啥重要? 文字和背景颜色对比度太低,视力不佳的用户(包括色弱、老年人,甚至在强光下看屏幕的普通人)会看不清内容。
  • 咋快速检查?
    • 浏览器开发者工具: 选中元素,在 StylesComputed 面板里找到 colorbackground-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. 滥用 divspan 做按钮 (Semantic HTML for Buttons)

  • 为啥重要? 这和第 2 点“键盘不可操作”高度相关,但更侧重于“语义”。屏幕阅读器无法识别一个 <div> 是按钮,即使用户能用鼠标点击它。它缺少按钮的角色(role)、状态(如 aria-pressed)等重要信息。
  • 咋快速检查?
    • 右键点击你看起来像按钮的东西,选择“检查”或“审查元素”。看看它在 DOM 里到底是 <button><a> 还是 <div class="looks-like-a-button">
    • 特别是那些用 SLDS 的 slds-button CSS 类但套在 divspan 上的情况。
  • 咋修复?
    • 用对标签: 如果它执行一个动作,用 <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)

  • 为啥重要? 屏幕阅读器用户经常使用标题(h1h6)来快速浏览和理解页面结构,就像视力正常用户扫读标题一样。如果标题层级混乱(比如从 h2 直接跳到 h4,中间没有 h3),会破坏这种导航体验,让页面结构难以理解。
  • 咋快速检查?
    • 使用浏览器开发者工具检查 DOM 结构,看看页面/组件中的 h1, h2, h3... 标签是否按逻辑层级排列?
    • 使用 a11y 检查插件(如 WAVE, axe DevTools),它们通常会高亮显示标题结构问题。
    • 简单来说:页面主标题是 h1 (通常 SLDS 应用级别会处理好),你的组件内部的章节标题应该是 h2,子章节是 h3,以此类推。不要跳级!
  • 咋修复?
    • 按顺序使用标题: 遵循 h1 -> h2 -> h3 -> h4 ... 的层级结构。在一个 h2 下面应该是 h3,而不是直接出现 h4
    • 使用 SLDS Heading Blueprint: 如果需要特定样式的标题,优先使用 SLDS 提供的标题样式类(如 slds-text-heading_large),但将它们应用在正确的 h 标签上,而不是用 divspan 伪装成标题。
    • 区分样式和语义: 不要因为某个级别的标题看起来太大或太小就跳级。标题的级别(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 开发工具箱里的一部分吧!你的用户会感谢你的!

代码洁癖晚期患者 LWC无障碍a11y前端开发Salesforce

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8955