使用NVDA屏幕阅读器时,ul中首个li标签无法通过向下箭头键导航的问题
可访问性问题修复方案:第一个列表项展开后NVDA无法用向下箭头读取内容
我帮你排查下这个问题,看起来第一个列表项展开后的内容没被NVDA正确识别到浏览流里,大概率是HTML语义结构不规范+焦点/ARIA属性处理不当导致的,咱们一步步来解决:
核心问题分析
你当前的代码把展开的内容<div>直接放在了<ul>下(作为<li>的同级元素),但根据HTML规范,<ul>的直接子元素只能是<li>,这种非法结构会让屏幕阅读器(尤其是对第一个列表项的语义校验更严格的NVDA)无法正确解析内容归属,这就是第一个项出问题、其他项能容错的关键原因。
另外还有两个次要问题:aria-expanded用了字符串值(标准应为布尔值),以及展开的内容容器不在焦点流里,导致阅读器无法主动捕获它。
具体修复步骤
1. 修正HTML语义结构,把展开内容放到<li>内部
把展开的内容容器移到对应列表项的<li>里面,确保<ul>的子元素只有<li>,恢复正确的列表语义:
<ul className="overview-menu" aria-label="菜单"> {options.map((opt, i) => ( <li key={opt.name} className={`overview-menu-option ${option?.name === opt.name ? 'active' : 'inactive'} ${contentBoxType}`} > <button className={`overview-menu-option-btn ${option?.name === opt.name ? 'active' : 'inactive'} ${contentBoxType}`} aria-expanded={!!(option && option.name === opt.name)} {/* 改为布尔值,符合ARIA规范 */} onClick={() => getContents(opt)} > {opt.name} <ChevronIcon aria-hidden="true" /> {/* 图标设为装饰性,隐藏给屏幕阅读器 */} </button> {/* 把内容容器放到<li>内部,添加tabindex让它能被聚焦 */} {isOptionClick && option?.name === opt.name ? ( <div key={`${opt.name}-contents`} className={`overview-menu-option-contents ${contentBoxType}`} tabindex="-1" {/* 允许聚焦但不进入Tab流,适配阅读器浏览模式 */} aria-label="展开的详情内容" data-name={opt.name} {/* 方便后续定位元素 */} > {option.contents} </div> ) : null} </li> ))} </ul>
2. 优化焦点管理,确保展开后内容被阅读器捕获
在getContents函数里,添加焦点自动跳转逻辑,当内容展开后主动聚焦到内容容器,让NVDA能立刻识别到新内容:
const getContents = (opt) => { // 原有逻辑:更新选中项状态 setOption(opt); setIsOptionClick(true); // 等待DOM更新后,聚焦到展开的内容容器 setTimeout(() => { const contentEl = document.querySelector(`.overview-menu-option-contents[data-name="${opt.name}"]`); if (contentEl) { contentEl.focus(); } }, 0); };
如果用React的useEffect会更优雅,避免定时器:
import { useEffect } from 'react'; useEffect(() => { if (isOptionClick && option) { const contentEl = document.querySelector(`.overview-menu-option-contents[data-name="${option.name}"]`); if (contentEl) { contentEl.focus(); } } }, [isOptionClick, option]);
3. 验证ARIA属性规范
把aria-expanded从字符串"true"/"false"改成布尔值true/false,虽然部分浏览器兼容字符串,但严格遵循WAI-ARIA规范能避免潜在的阅读器解析问题。
测试验证
修复后用NVDA测试:
- 按Tab键导航到第一个列表项的按钮,NVDA会提示按钮状态和文本
- 按下Enter展开内容,焦点会自动跳转到内容容器
- 按向下箭头键,NVDA会正常读取展开的内容文本
内容的提问来源于stack exchange,提问作者dsoup2
相关产品推荐
相关产品推荐

