标准 · ARIA

属性 控件状态

aria-haspopup

告知辅助技术:激活此控件将打开一个弹出层,并说明弹出层的类型。可接受的值为 "menu"、"listbox"、"tree"、"grid"、"dialog" 或 "true" / "false"。应与 aria-expanded 配合使用,以便辅助技术同时通报弹出层的展开状态。

适用场景

凡打开临时覆盖层的控件均应使用此属性——例如触发菜单的按钮、在组合框中打开列表框的输入框、弹出对话框的图标按钮。该属性让屏幕阅读器能够朗读诸如”筛选,菜单按钮”或”搜索,有弹出层”之类的内容,告知用户激活该控件将展开更多界面,而非导航或提交。

仅切换页面内某区域的控件不需要使用此属性——展示型控件(disclosure widget)应单独使用 aria-expanded;被展示的内容是页面的组成部分,而非弹出层。

行为说明

此属性接受一组固定的标记值:

  • "menu" — 打开 role="menu"(菜单按钮最常用的值)。
  • "listbox" — 打开 role="listbox",用于自定义组合框。
  • "tree" — 打开 role="tree"
  • "grid" — 打开 role="grid"(日期选择器常用)。
  • "dialog" — 打开 role="dialog"role="alertdialog"
  • "true" — 历史原因下等同于 "menu";建议使用具体值。
  • "false" — 明确表示”无弹出层”;为默认值。

aria-haspopup 应与 aria-expanded="true|false" 配合使用,以便辅助技术同时通报弹出层当前是否已展开。两者职责不同——haspopup 表示”存在弹出层”,expanded 表示”弹出层当前是否可见”。

常见错误

  • 在打开自定义日期选择器(实为 grid 或 dialog)的按钮上使用 aria-haspopup="true"——辅助技术将其朗读为”菜单按钮”,用户按下向下方向键时期待看到菜单项。
  • 遗漏 aria-expanded。辅助技术只通报”有弹出层”,而不通报展开/折叠状态,用户无法判断点击操作是否生效。
  • 对实际上不会打开弹出层的控件添加 aria-haspopup,误导用户——用户听到该提示后发现什么都没有出现。
  • 在跳转至新页面的链接上使用 aria-haspopup。这不是弹出层;让链接保持链接即可。
  • 遗漏将焦点移入 dialog 弹出层或移至 menu 的第一个 menuitem。该属性只声明弹出层类型,不负责管理焦点。
  • 设置了 aria-haspopup="dialog",却未在弹出元素上设置 role="dialog",导致承诺的语义从未出现。

示例

<!-- 菜单按钮 -->
<button
  type="button"
  id="filter-btn"
  aria-haspopup="menu"
  aria-expanded="false"
  aria-controls="filter-menu"
>
  筛选
</button>
<ul id="filter-menu" role="menu" hidden>
  <li role="menuitem">全部</li>
  <li role="menuitem">未读</li>
  <li role="menuitem">已标记</li>
</ul>