You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在<option>标签中使用aria-describedby实现选项后朗读描述?

实现下拉选项关联描述的可行方案

原生<select>和<option>对aria-describedby的支持存在兼容性问题,且aria-labelledby的触发逻辑不符合需求,以下是两种可行的解决思路:

方案1:视觉隐藏描述文本到选项内

将描述内容直接嵌入<option>中,通过CSS将描述文本视觉隐藏,既保证视觉体验不受影响,又能让屏幕阅读器完整朗读选项内容+描述。

示例代码:

<style>
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
</style>

<select>
  <option>Option A <span class="sr-only">This is a description for option A</span></option>
  <option>Option B <span class="sr-only">This is a description for option B</span></option>
  <option>Option C <span class="sr-only">This is a description for option C</span></option>
</select>

这个方案的核心是利用视觉隐藏类,让描述文本仅对屏幕阅读器可见,切换选项时(包括上下箭头导航),阅读器会完整朗读选项的全部内容。

方案2:自定义下拉组件(模拟原生select)

如果需要更灵活的控制,可使用ARIA角色构建自定义下拉组件,原生listbox和option角色对aria-describedby支持更完善,能完全实现预期的播报逻辑。

示例代码:

<div role="combobox" aria-expanded="false" aria-haspopup="listbox" id="custom-select">
  <span id="selected-option">Select an option</span>
  <button aria-label="Open dropdown">▼</button>
</div>

<ul role="listbox" id="option-list" hidden>
  <li role="option" aria-describedby="desc-a" tabindex="0">Option A</li>
  <li role="option" aria-describedby="desc-b" tabindex="0">Option B</li>
  <li role="option" aria-describedby="desc-c" tabindex="0">Option C</li>
</ul>

<p id="desc-a" class="sr-only">This is a description for option A</p>
<p id="desc-b" class="sr-only">This is a description for option B</p>
<p id="desc-c" class="sr-only">This is a description for option C</p>

<script>
// 交互逻辑:展开/收起列表、键盘导航、选项选中
const combobox = document.getElementById('custom-select');
const button = combobox.querySelector('button');
const listbox = document.getElementById('option-list');
const options = listbox.querySelectorAll('[role="option"]');

button.addEventListener('click', () => {
  const isExpanded = combobox.getAttribute('aria-expanded') === 'true';
  combobox.setAttribute('aria-expanded', !isExpanded);
  listbox.hidden = isExpanded;
  if (!isExpanded) options[0].focus();
});

listbox.addEventListener('keydown', (e) => {
  let currentIndex = Array.from(options).findIndex(opt => opt === document.activeElement);
  switch(e.key) {
    case 'ArrowDown':
      e.preventDefault();
      const nextIndex = (currentIndex + 1) % options.length;
      options[nextIndex].focus();
      break;
    case 'ArrowUp':
      e.preventDefault();
      const prevIndex = (currentIndex - 1 + options.length) % options.length;
      options[prevIndex].focus();
      break;
    case 'Enter':
    case ' ':
      e.preventDefault();
      document.getElementById('selected-option').textContent = e.target.textContent;
      combobox.setAttribute('aria-expanded', 'false');
      listbox.hidden = true;
      combobox.focus();
      break;
  }
});

options.forEach(opt => {
  opt.addEventListener('click', () => {
    document.getElementById('selected-option').textContent = opt.textContent;
    combobox.setAttribute('aria-expanded', 'false');
    listbox.hidden = true;
    combobox.focus();
  });
});
</script>

自定义组件需要自行实现键盘导航、展开收起等交互,但能完全控制屏幕阅读器的播报内容,当用上下箭头切换选项时,阅读器会自动朗读选项内容+关联的描述文本。

内容的提问来源于stack exchange,提问作者gperezinf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 04:36:13