php - 使用 WordPress 创建正确的 ARIA 菜单

标签 php wordpress accessibility wai-aria

我为 WordPress 创建了一个自定义 Nav Walker,以将正确的 ARIA 角色添加到 wp_nav_menu() 的输出中。功能。检查出来没问题。但我一直在尝试做两件事。

我的步行器产生以下输出:

<nav id="siteNav" role="navigation">
<ul id="menuMain" class="menu" role="menubar">
    <li id="menu-item-1698" class="menu-item" role="presentation">
        <a href="http://localhost/" role="menuitem">Front Page</a>
    </li>
    <li id="menu-item-1697" class="menu-item" role="presentation">
        <a href="http://localhost/blog/" role="menuitem">Blog</a>
    </li>
    <li id="menu-item-1694" class="menu-item" role="presentation">
        <a href="http://localhost/sample-page/" role="menuitem">Sample Page</a>
    </li>
    <li id="menu-item-1695" class="menu-item" role="presentation">
        <a href="http://localhost/page-b/" role="menuitem">Page B</a>
    </li>
    <li id="menu-item-1696" class="menu-item" role="presentation">
        <a href="http://localhost/page-a/" role="menuitem">Page A</a>
    </li>
    <li id="menu-item-1699" class="menu-item" role="presentation">
        <a href="http://localhost/" role="menuitem">Front Page</a>
    </li>
    <li id="menu-item-1701" class="menu-item" role="presentation">
        <a href="http://localhost/level-1/" role="menuitem">Level 1</a>
        <ul class="sub-menu" role="menu" aria-expanded="false">
           <li id="menu-item-1702" class="menu-item" role="presentation">
               <a href="http://localhost/level-1/level-2b/" role="menuitem">Level 2b</a>
            </li>
           <li id="menu-item-1703" class="menu-item" role="presentation">
               <a href="http://localhost/level-1/level-2a/" role="menuitem">Level 2a</a>
            </li>
           <li id="menu-item-1704" class="menu-item" role="presentation">
               <a href="http://localhost/level-1/level-2/" role="menuitem">Level 2</a>
               <ul class="sub-menu" role="menu" aria-expanded="false">
                  <li id="menu-item-1705" class="menu-item" role="presentation">
                      <a href="http://localhost/level-1/level-2/level-3b/" role="menuitem">Level 3b</a>
                   </li>
                  <li id="menu-item-1706" class="menu-item" role="presentation">
                      <a href="http://localhost/level-1/level-2/level-3a/" role="menuitem">Level 3a</a>
                   </li>
               </ul>
            </li>
        </ul>
    </li>
</ul>

我现在想做的是将某种 ID 添加到 <a>元素是 <ul class="sub-menu"> 的同级元素元素并在 aria-labelledby 中引用该 ID属性。

因此包含子菜单的菜单项将如下所示:

<li id="menu-item-1704" class="menu-item" role="presentation">
   <a href="http://localhost/level-1/level-2/" role="menuitem" id="{ID}">Level 2</a>
   <ul class="sub-menu" role="menu" aria-expanded="false" aria-labelledby="{ID}">
       <li id="menu-item-1705" class="menu-item" role="presentation">
          <a href="http://localhost/level-1/level-2/level-3b/" role="menuitem">Level 3b</a>
       </li>
       <li id="menu-item-1706" class="menu-item" role="presentation">
          <a href="http://localhost/level-1/level-2/level-3a/" role="menuitem">Level 3a</a>
       </li>
    </ul>
 </li>

我的助行器的代码:

类 Walker_ARIA_Nav_Menu 扩展了 walker {

public $tree_type = array( 'post_type', 'taxonomy', 'custom' );


public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );


public function start_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat( "\t", $depth );
    $output .= "\n$indent<ul class=\"sub-menu\" role=\"menu\" aria-expanded=\"false\" aria-hidden=\"true\">\n";
}


public function end_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat( "\t", $depth );
    $output .= "$indent</ul>\n";
}


public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = 'menu-item-' . $item->ID;


    $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );

    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
    $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

    $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth );
    $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

    $output .= $indent . '<li' . $id . $class_names .' role="presentation">';

    $atts = array();
    $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
    $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
    $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
    $atts['href']   = ! empty( $item->url )        ? $item->url        : '';


    $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );

    $attributes = '';
    foreach ( $atts as $attr => $value ) {
        if ( ! empty( $value ) ) {
            $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
            $attributes .= ' ' . $attr . '="' . $value . '"';
        }
    }


    $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );

    $item_output = $args->before;
    $item_output .= '<a'. $attributes .' role="menuitem">';
    $item_output .= $args->link_before . $title . $args->link_after;
    $item_output .= '</a>';
    $item_output .= $args->after;


    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}


public function end_el( &$output, $item, $depth = 0, $args = array() ) {
    $output .= "</li>\n";
}
} // End Walker_ARIA_Nav_Menu Class

最佳答案

我将回答这个问题,假设您正在为网站或类似网站构建此菜单(而不是您在所选操作系统上安装的应用程序,该应用程序的行为应该与 native 操作系统菜单相同)。

话虽这么说,我相信您在这里遇到了一个整体 ARIA 问题,这使得您问题中的 PHP 部分变得毫无意义。

立即考虑,给出您建议的以下 HTML:

<ul class="sub-menu" role="menu" aria-expanded="false" aria-labelledby="{ID}">
    <li id="menu-item-1705" class="menu-item" role="presentation">
       <a href="http://localhost/level-1/level-2/level-3b/" role="menuitem">Level 3b</a>
    </li>
    <li id="menu-item-1706" class="menu-item" role="presentation">
       <a href="http://localhost/level-1/level-2/level-3a/" role="menuitem">Level 3a</a>
    </li>
 </ul>

…您应该跳过aria-labelledby。由于该元素上没有制表位(我不是指 tabindex),因此屏幕阅读器没有理由宣布它,因此它不会。此外,如果它确实有制表位,则 aria-labelledby 会覆盖该元素上可能存在的可访问名称。 From the horse's mouth :

The specified behavior of aria-labelledby is that the associated label text is announced instead of the link text (not in addition to the link text). When the link text itself should be included in the label text, the ID of the link should be referenced as well in the string of IDs forming the value of the aria-labelledby attribute.

现在谈谈整个方法。我建议您根本不要在这里使用 role="menu"role="menuitem" 。使用它们可以让屏幕阅读器用户期望整个菜单将充当他/她的操作系统中的菜单栏。我不知道您是否已准备好所有必要的键盘交互来实现这一点,但根据我的经验,这种情况很少发生。

如果您不同意我的观点,请查看以下一些来源......

Using ARIA menus :

Menu widgets must provide keyboard support to navigate all the menu items in the menu. Keyboard support for a menu typically include the cursor keys to navigate between the menu items and open and close popupmenus.

然后,它继续描述您需要映射的所有键盘交互,并提供一个示例 HTML block 。您可能会注意到,它不会按照您使用 ARIA 属性的方式使用它们。

这种菜单出现在WebAIM mailing list上经常。这是 one of many discussions 的摘录:

But to take a step back, it may be first useful to ensure that an ARIA menubar is actually appropriate. This is not typically appropriate for web site navigation - it's intended for a web application's menu bar (think "File...", "Edit...", etc.).

如果你看一下当前最先进的可访问菜单,这个就是 accessible mega-menu from Adobe ,您将看到 Adob​​e 明确说明了它不使用 role="menu" 也不使用 role="menuitem" 的原因:

We don't use role="menu" for the menu container and role="menuitem" for each of the links therein, because if we do, assistive technology will no longer interpret the links as links, but instead, as menu items, and the links in our global navigation will no longer show up when a screen reader user executes a shortcut command to bring up a list of links in the page.

最后,我鼓励您构建理想菜单的静态 HTML 版本,然后使用屏幕阅读器进行测试。您可以获得 NVDA for Windows 的副本免费(尽管 you really should donate ),并且 VoiceOver 已预装在 Mac 上。

顺便说一句,WordPress has a support forum dedicated to accessibility ,所以你也可以在那里问。

关于php - 使用 WordPress 创建正确的 ARIA 菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37715775/

相关文章:

mysql - Mariadb 加载,但几分钟后崩溃。服务器从 "snapshot"恢复后发生

cocoa - 将文本从我的 cocoa 应用程序复制到另一个应用程序

html - 标签 "for"和输入 "id"

php - 使用 FFMPEG 在特定时间从视频中获取帧(PHP)

PHP 常量数组访问

php - 如果不是非主行的副本,则sql查询仅更新

php - 显示标签与页面标题匹配的帖子

php - slider 未显示 : setREVStartSize is not defined

android - fragment 在替换后没有获得可访问性焦点

php - 如何使用 PHP 7 启用 MySQL