本文约 4,074 字,预计阅读 11 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:加了高对比模式,无障碍依然不合格
很多无障碍改造的起点是”领导要求”或”验收指标”,落到执行上就变成换配色。但真正的痛点非常具体:60 岁的用户看不清浅灰正文;使用读屏浏览器的用户点进你的首页会先听四十多条”导航链接”;操作有障碍的用户无法用鼠标完成下拉,只能按 Tab,却发现焦点完全看不见。判断一个站是否真的友好,最快的方法是放下鼠标,只用键盘从左走到右。
原理分析:无障碍的四项原则与可量化指标
国际通行的是 WCAG(Web Content Accessibility Guidelines)2.1,AA 级是国内项目最常见的达标要求。它的四项原则简称 POUR:可感知(Perceivable)、可操作(Operable)、可理解(Understandable)、健壮性(Robust)。落到 WordPress 站点,最常被量化引用的是:
- 文本与背景对比度:正文 ≥ 4.5:1,大字号(≥18.66px 粗体或 ≥24px)≥ 3:1。
- 键盘可达:所有交互元素必须能用 Tab 到达且焦点状态可见。
- 替代文本:非装饰性图片必须有
alt;装饰图用alt=""。 - 表单标签:每个输入框必须有程序关联的
<label>。 - 动效抑制:系统在用户开启”减少动态效果”时,应关闭大幅动画。
| 原则 | 检查项 | 常见不合格表现 |
|---|---|---|
| 可感知 | 对比度、alt、字幕 | 浅灰小字、空 alt |
| 可操作 | 焦点可见、跳过导航 | Tab 找不到焦点位置 |
| 可理解 | 错误提示、焦点顺序 | 提示只有红框无言文字 |
| 健壮性 | 语义标签、ARIA | 用 div 当按钮 |
保姆级实操
步骤 1:先扫一遍现状。 用 axe DevTools 或 WAVE 浏览器扩展跑首页与典型列表页,先把 contrast、missing-form-label、image-alt 三类问题解决掉,通常能一次性消掉七成以上告警。
步骤 2:修正对比度。 别靠肉眼,用 CSS 变量统一一套配色,并检查所有”次要信息”色值:
:root {
--mf-text: #1f2937; /* 主文本,与白底对比度约 13:1 */
--mf-muted: #4b5563; /* 次要文本,约 7:1,仍高于 4.5:1 */
--mf-link: #1d4ed8;
--mf-bg: #ffffff;
}
.mf-card__desc { color: var(--mf-muted); }
a { text-decoration: underline; } /* 不要仅用颜色区分链接 */
步骤 3:让焦点看得见。 WordPress 自带的 .screen-reader-text 就是为了读屏器准备的“跳过导航”区域,务必保证主题正确输出并被 CSS 正确处理:
<a class="skip-link screen-reader-text" href="#content">跳到主要内容</a>
.skip-link:focus {
position: static;
display: inline-block;
padding: 8px 12px;
background: #fff;
color: #1f2937;
outline: 3px solid #1d4ed8;
}
.screen-reader-text {
border: 0; clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%); height: 1px; width: 1px;
overflow: hidden; position: absolute; white-space: nowrap;
}
a:focus-visible, button:focus-visible, input:focus-visible {
outline: 3px solid #1d4ed8;
outline-offset: 2px;
}
步骤 4:给视频加字幕。 用 WebVTT 字幕文件,通过 <track> 元素关联,并标明语言:
<video controls preload="metadata" poster="/poster.jpg">
<source src="/video/lesson.mp4" type="video/mp4">
<track kind="captions" src="/subs/lesson.zh-Hans.vtt" srclang="zh-Hans" label="中文字幕" default>
<track kind="descriptions" src="/subs/lesson.desc.vtt" srclang="zh-Hans" label="内容描述">
</video>
WordPress 里可以让自定义字段存字幕 URL,再用 wp_VIDEO_SHORTCODE 相关钩子注入:
add_filter( 'wp_video_shortcode', function ( $output, $atts ) {
if ( empty( $atts['subtitle'] ) ) {
return $output;
}
$track = sprintf( '<track kind="captions" src="%s" srclang="zh-Hans" label="中文字幕" default>',
esc_url( $atts['subtitle'] ) );
return str_replace( '</video>', $track . '</video>', $output );
}, 10, 2 );
步骤 5:抑制过大动效。 尊重系统的减少动效偏好:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
scroll-behavior: auto !important;
}
}
步骤 6:表单必有标签与可读错误。 不要只用 placeholder 当标签:
<label for="mf-email">邮箱地址</label>
<input id="mf-email" name="email" type="email" autocomplete="email" aria-describedby="mf-email-err">
<p id="mf-email-err" role="alert">邮箱格式不正确,请检查是否缺少 @</p>
步骤 7:语义<|hy_place▁holder▁no▁813|> links。 用 <button> 而非 <div onclick>;下拉菜单用 aria-expanded 标状态;弹窗用 role="dialog" 并在关闭后把焦点还给触发元素。WordPress 前端表单提交与安全
常见踩坑
- 只把颜色对比改成深色却被后面新增的新配色还原,缺乏统一变量导致反复。
- 案例: 某单位站在 nav 上用了纯 CSS
:hover显示下拉,触摸与键盘都不可用,验收时被判定为”仅鼠标可用”,返工两周。 - 每张图片都写
alt="图片",读屏用户听到一串”图片图片”。 - 删除了
outline却没补:focus-visible,键盘用户彻底看不见焦点。 - 视频用了第三方播放器 iframe,字幕只能通过对方后台配置,忘了填等于没有。
- 关心”放大 200% 不丢内容”,但布局用 px 固定宽高,缩放后内容被裁切。
- 页面 title 与 heading 层级乱跳(h1 后直接 h4),屏幕阅读器导航困难。WordPress 主题结构与模板层级
总结
判断改造是否到位的标准很简单:能否只靠键盘完成核心任务、读屏软件能否正确朗读主要内容、以及 prefers-reduced-motion 下是否还能正常使用。行动清单:axe 扫描 → 统一对比度变量 → 焦点可见 + 跳过导航 → 字幕 WebVTT → 表单 label 与错误提示 → 减少动效。无障碍不是一次性项目,把它写进主题规范与 PR 检查项,才能真正保持住。
