Accessibility 辅助功能总结

总结一下接手项目以来Accessibility的一些收获,这个产品要求支持辅助功能,虽然已经是按照最低要求,但做起来即要考虑全键盘可以操作,也要考虑所有显示的内容和需要交互的内容可以被讲述人读出来,还要考虑高对比下的样式兼容,也是有不少的维护开发成本。

css可以通过特定选择器来指定高对比度模式下的样式

js 复制代码
@media screen and (forced-colors: active) {
 color: ButtonText;
 backgroundColor: ButtonFace;
}
// 判断系统主题
@media (prefers-color-scheme: dark) {
  .brand-text {
    color: #ffffff;
  }
}

可用的内置变量:

1. Button
Keyword Meaning
ButtonBorder Border color of native buttons/controls (e.g., the outline of a button).
2. Text & content
Keyword Meaning
Canvas Background color of the main content area (e.g., a window's background).
CanvasText Text color for content on the Canvas background.
LinkText Color of unvisited hyperlinks (matches system's default link color).
VisitedText Color of visited hyperlinks.

3. Highlight & selection

Keyword Meaning
Highlight Background color of selected text/elements (e.g., highlighted text).
HighlightText Text color of selected content (contrasts with Highlight).

4. UI chrome (window/frame elements)

Keyword Meaning
ActiveBorder Border color of active windows/dialogs.
ActiveCaption Background color of the title bar of an active window.
ActiveCaptionText Text color in the title bar of an active window.
InactiveBorder Border color of inactive windows/dialogs.
InactiveCaption Background color of the title bar of an inactive window.

5. Status & feedback

Keyword Meaning
GrayText Color of disabled text (e.g., grayed-out buttons/options).
InfoBackground Background color of tooltip/info panels.
InfoText Text color in tooltip/info panels.

html inert 属性

学到了一个新的且很重要的html属性 inert,这个词表示 "使惰性",它可以让元素中的用户交互事件都失效,适合展示顶层窗口时,把交互trap到当前窗口中。 `

js 复制代码
export function disableApp() {
  document.getElementById('app')?.setAttribute('inert', '')
}
export function enableApp() {
  document.getElementById('app')?.removeAttribute('inert')
}

焦点 管理

如果不是做 accessibility, 我都不知道聚焦是一个这个难以处理的东西。不过也是因为这个项目之前给第三方组件库提了需求,要求弹窗弹出来自动聚焦第一个可聚焦的元素,但是可能没区分好触发方式:

  1. 键盘导航触发 (应该自动聚焦)
  2. 鼠标点击触发(不应该自动聚焦)
  3. 编程式触发 xxx.focus() (不应该自动聚焦,但组件库聚焦了)

为了不牵扯第三方去修改,我们监听了focus事件,发现有自动聚焦但不想聚焦的时候,就去设置blur,其中监听事件有两种:

js 复制代码
parentElement.addEventListener('focus', handlefocus, { capture: true, once: true })
等价于
parentElement.addEventListener('focusin', handlefocus, { once: true }) //childElement也会触发
}

几种关于聚焦元素的伪类选择器

js 复制代码
*:focus
*:focus-within
*:focus-visible  如果没有意外情况,这个选择器本身就只有在键盘导航时才显示样式,已经和鼠标做了区分

判断DOM元素是否可聚焦或者已经聚焦

js 复制代码
// 检查焦点相关状态
function diagnoseFocus(element) {
  return {
    hasFocusVisible: element.matches(':focus-visible'),
    hasFocus: element.matches(':focus'),
    isActive: element.matches(':active'),
    tabIndex: element.tabIndex,
    computedOutline: getComputedStyle(element).outline,
    focusVisibleSupported: CSS.supports('selector(:focus-visible)')
  };
}

// 实时监控
document.addEventListener('focusin', (e) => {
  console.log('焦点诊断:', diagnoseFocus(e.target));
});

其实非预期的行为大多出现在编程式触发,让组件库在调用 focus()方法的时候加一个 flag,使用组件库的控制起来会方便很多。

相关推荐
月走乂山1 天前
DSH 桌面版用 DeepSeek 报 REQUEST_EXTENSION 的根因定位与修复
electron·node.js·插件系统·deepseek·bug排查·dsh·deepseek harness
mont evergreen2 天前
一封从外部世界寄来的信:二维码数据如何穿越三重门,抵达你的屏幕
electron·vue·事件
fellow992 天前
DSH Desktop:把 DeepSeek Harness 变成真正的桌面应用
electron·agent·ai编程·deepseek
CDwenhuohuo3 天前
electron pc项目打包成桌面端
前端·javascript·electron
不可能片场4 天前
命令行中文变问号 我用环境变量救了场
前端·electron
不可能片场5 天前
AI视频口型对齐 用音频驱动说话镜头
前端·electron
Zoom5 天前
【开源】7 天,我用 Rust 复刻了 FinalShell!Rhost v1.0.0 发布
rust·electron·shell
爱丶不疚7 天前
Electron: Sentry 都采集了什么?你知道吗
前端·electron
格数致用7 天前
03- Luckysheet与Vue3+Electron集成实战指南
electron·vue3·luckysheet