有没有办法在不影响可访问性的情况下将导航菜单的打开/关闭按钮放在导航元素之外?

问题描述

到目前为止,我找不到这个问题的明确答案/解释。

从可访问性的角度来看,这似乎没有争议:

示例 A:

<header>

  <!-- Other stuff like a logo or other buttons -->

  <nav>
    <button>Menu</button>

    <ul>
      <li><a href="">Page 1</a></li>
      <li><a href="">Page 2</a></li>
      <li><a href="">Page 3</a></li>
    </ul>
  </nav>
</header>

然而,从 UI 设计的角度来看,这可能是有限制的。拥有这样的标记将是一种解放:

示例 B:

<header>

  <!-- Other stuff like a logo or other buttons -->

  <button>Menu</button>

  <nav>
    <ul>
      <li><a href="">Page 1</a></li>
      <li><a href="">Page 2</a></li>
      <li><a href="">Page 3</a></li>
    </ul>
  </nav>
</header>

在任何一种情况下,如果导航已关闭,则不必隐藏 nav 元素,使用 display none 隐藏 ul 元素就足够了。

虽然在示例 B 中,从 UX 的角度来看,隐藏 nav 元素(即整个导航)可能会更好,因为小时候没有打开/关闭按钮的关闭导航可能会令人困惑,但我是不确定。

解决方法

简答

选项 1 更好,因为语义使关系变得明显。选项 2 可以通过 aria 属性进行访问(假设用户屏幕阅读器和浏览器组合支持它们)。

选择选项 1,除非绝对无法通过定位等实现您想要的设计(我认为这种情况非常罕见!)

更长的答案

80% 以上的可访问性是语义和​​语义关系。

在您的第一个示例中,控制菜单的按钮是导航的一部分,这很有意义。如果这是一个模式类型菜单(您没有指定,但模式表明它可能会更容易),这还有一个额外的好处,可以使任何焦点陷印和管理变得更加容易。

在您的第二个示例中,在隐藏 <nav> 时使用空的 <ul> 元素并不理想,因为按地标导航仍可能导致某些屏幕阅读器显示地标,所以当用户导航到它时,他们会发现它是空的。

另一种选择是完全隐藏 <nav> 元素,这也不理想,因为在按地标导航时不会有 <nav>

如果你想使用第二个标记,尽管有这些缺点,WAI-ARIA 可以帮助定义按钮和菜单等之间的关系。

通过在 <button> 上使用 aria-haspopuparia-owns(不要忘记 aria-expanded,但这两个示例都需要)。

请注意: aria-controls 实际上是更合适的 aria 属性,而不是 aria-owns,而是 support is not great for aria-controls sadly

最后的想法

您再次没有指定这是否是模式类型菜单,但我假设它来自模式。

因此 you need to consider focus trapping 并明确菜单按钮根据菜单状态充当打开和关闭按钮。为此,您可以在按钮内使用一些 visually hidden text 来指示状态,这比单独依赖 aria-expanded 更好:

<!--closed state-->
<button aria-expanded="false"><span class="visually-hidden">Open </span>Menu</button>
<!--opened state-->
<button aria-expanded="true"><span class="visually-hidden">Close </span>Menu</button>