本文介绍如何使用语义化 元素配合 aria-pressed 实现符合无障碍标准的可键盘操作切换按钮,确保用户可通过 Tab 键聚焦、Space/Enter 键触发切换,并保持视觉状态同步。
本文介绍如何使用语义化 `
在构建可访问的 UI 组件时,仅依赖 +
推荐方案:改用语义化
aria-pressed 是专为切换按钮(toggle button)设计的 ARIA 属性。当 role="button" 元素同时拥有 aria-pressed(值为 "true" 或 "false")时,辅助技术会将其识别为状态可切换的控件,并自动支持 Space 和 Enter 键触发 —— 这正是浏览器对原生
以下是完整、可直接使用的实现:
✅ HTML 结构(语义清晰,开箱即用)
<button id="toggle" type="button" aria-pressed="false" aria-label="切换为月付价格"> <span class="toggle-inner"></span> </button>
- type="button" 防止表单意外提交;
- aria-label 提供明确的可访问名称(替代 alt 或隐藏文本),屏幕阅读器将朗读“切换为月付价格,未按下”;
- 内部 作为滑块容器,便于 CSS 控制视觉反馈。
✅ JavaScript 逻辑(简洁可靠)
const toggleBtn = document.getElementById("toggle");
const basic = document.getElementById("basic");
const professional = document.getElementById("professional");
const master = document.getElementById("master");
function toggleContent() {
const isMonthly = toggleBtn.getAttribute("aria-pressed") === "true";
// 切换状态
toggleBtn.setAttribute("aria-pressed", !isMonthly);
// 更新价格内容
if (isMonthly) {
basic.textContent = "199.99";
professional.textContent = "249.99";
master.textContent = "399.99";
} else {
basic.textContent = "19.99";
professional.textContent = "24.99";
master.textContent = "39.99";
}
}
// 直接监听 click 即可 —— Space/Enter 自动触发 click 事件
toggleBtn.addEventListener("click", toggleContent);
⚠️ 注意:不要监听 keydown 或 keypress。原生
✅ CSS 样式(状态驱动,平滑过渡)
#toggle {
background: #e0e0e0;
width: 4.4rem;
height: 2.4rem;
border: none;
border-radius: 2rem;
padding: 0;
cursor: pointer;
position: relative;
outline: none; /* 由:focus-visible 更优雅地控制焦点样式 */
}
#toggle:focus-visible {
outline: 2px solid #007bff;
outline-offset: 2px;
}
.toggle-inner {
position: absolute;
top: 0.2rem;
left: 0.2rem;
width: 2rem;
height: 2rem;
background: white;
border-radius: 50%;
transition: transform 0.25s ease;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
#toggle[aria-pressed="true"] .toggle-inner {
transform: translateX(calc(100% - 0.4rem));
}
- 使用 [aria-pressed="true"] 选择器精准控制视觉状态,与逻辑完全同步;
- :focus-visible 替代全局 :focus,避免鼠标点击时出现干扰性轮廓线;
- transform 实现高性能滑动动画。
✅ 可访问性验证要点
- ✅ Tab 键可聚焦按钮;
- ✅ Space/Enter 键可切换状态并触发内容更新;
- ✅ 屏幕阅读器朗读:“切换为月付价格,未按下” → 点击后变为:“切换为月付价格,已按下”;
- ✅ 高对比度模式下颜色与状态仍清晰可辨;
- ✅ 无 JavaScript 降级时,按钮至少保留可点击区域(虽功能失效,但结构不崩溃)。
总结:抛弃 checkbox+label 的 hack 方案,拥抱语义化










