无障碍Accessibility
无障碍是组件的默认行为,不是可选项。这一页分两部分:库替你保证了什么,以及哪些事只有使用者才能做。每个组件页的末尾还有该组件自己的键盘和读屏说明。
库的通用保证
语义
用对的原生元素:按钮是 <button type="button">,开关、复选框、单选是真的 <input>,链接是 <a>。复合组件按 WAI-ARIA 的模式带上 role 和 aria-* 属性。
键盘
Tab 进出,方向键在组内移动,Home / End 到两端,Enter / Space 触发,Esc 关闭。组内用 roving tabindex 或 aria-activedescendant,一个组只占一个 Tab 停靠点。
焦点环
所有可交互元素共用一套焦点环:2px 强调色描边,只在键盘聚焦(:focus-visible)时出现,指针点击不会留下。
焦点管理
模态的悬浮卡片会圈住焦点、锁住页面滚动,关闭后把焦点还给触发它的元素;非模态的面板不圈焦点,焦点在里面时 Esc 关闭。
减弱动效
系统开了“减弱动态效果”时,全局倍率 --ok-ms 变成 0:位移和缩放归零,只保留状态切换。脚本动画走 animate(),同样受这个倍率控制。
对比度
文字色 --ok-text、--ok-text-2 和各状态的 -text 色在两套主题的表面上都不低于 4.5:1。状态除了颜色还有图标、文字或形状做第二种提示。
触屏尺寸
触屏设备上控件高度自动抬到 36 / 44 / 52,点按区域不小于 44px;悬停样式都包在 @media (hover: hover) 里,不依赖悬停才能看到的信息。
播报
Toast、表单错误、复制结果这类变化通过 aria-live 播报;危险类通知用 assertive,其余用 polite。
焦点环
点一下预览区的空白处,然后按 ⇥ 依次走过这些控件。自己写的可交互元素加上类名 ok-focusable 就能得到同一套焦点环。
使用者要做的事
下面这些,库没法替你决定。
- 给没有可见文字的控件起名字。图标按钮、没有标签的开关和滑块、搜索框,都要有
aria-label或aria-labelledby。 - 给区域和导航起名字。页面上有多个
Nav、Toolbar、ScrollArea、悬浮卡片时,用aria-label或标题把它们区分开。 - 保持标题层级。每页一个
h1,往下逐级。Heading的level决定语义,variant决定大小,两者可以分开选;CardHeader、Section、FloatingHeader都能指定标题级别。 - 不要只靠颜色。状态要有文字或图标;图表、色板要有名字。
- 表单要有标签和错误文字。用
Field包住控件,标签、提示、错误信息会自动通过id和aria-describedby接上。 - 图片要有替代文字。
Avatar的name就是读屏读到的名字;有含义的Icon给label,纯装饰的不用管,默认对读屏隐藏。 - 不要去掉焦点环。不要写
outline: none覆盖:focus-visible。 - 谨慎使用 motion="full"。它会无视系统的减弱动效设置,只应该在用户自己明确选择时启用。
名字
颜色之外的第二种提示
自查清单
- 只用键盘走一遍主要流程:每个能点的东西都能 Tab 到,焦点始终看得见,浮层能用 Esc 关掉,关掉后焦点回到原处。
- 打开读屏走一遍:每个控件都有名字和角色,状态变化(展开、选中、错误)能被读出来。
- 把系统设成“减弱动态效果”:界面仍然可用,没有大幅位移。
- 把窗口缩到 375px 宽、把浏览器缩放调到 200%:内容不横向溢出,没有被裁掉的文字。
- 切到深色主题再看一遍对比度。