【问题标题】:Hidden aria labels in HTML table (for screen reader accessibility)HTML 表格中隐藏的 aria 标签(用于屏幕阅读器可访问性)
【发布时间】:2015-01-07 18:24:19
【问题描述】:

在我的网页中,我需要创建一个表,该表具有根据某些用户配置可见或隐藏的标题行。该表还需要完全可访问(具体来说,由于表可能很长,我希望读取行/列标题的快捷方式可以工作)。我只有 ChromeVox 可以测试(我会从我找到的博客文章中详细介绍与其他读者的行为)。

我当前的布局看起来和这个类似:

CSS:

.table-header-show {
}

.table-header-hide {
  display: none;
}

HTML:

<table>
  <!-- ${show} is used to choose the right class the user configuration -->
  <thead class="table-header-${show}">
    <tr>
      <th>Name</th>
      <th>Value 1</th>
      <th>Value 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Doe</td>
      <td>Value 1a</td>
      <td>Value 2a</td>
    </tr>
  </tbody>
</table>

当标题可见时,完全没有问题。当标题隐藏时,取决于屏幕阅读器是否读出这些标签:

  • 我希望通过屏幕阅读器使用常规导航时跳过标题行*,但使用标题行来宣布列标签
  • 使用 ChromeVox,第一个工作(在导航中跳过)但第二个失败(隐藏行不用于标记列)
  • 再次使用 ChromeVox,将隐藏移动以声明为style 属性而不是class,使两种所需的行为都起作用
  • 根据我发现的一篇博客文章,screen readers somtimes ignore display: none 是为了说出内容,有时他们不会 - 所以我不确定我是否可以依靠这种隐藏来实现我的目的(隐藏导航,用于标记)

那么,我怎样才能以跨浏览器阅读器的方式实现我想要的行为?

  • AFAIK,屏幕外/1px 大小隐藏的问题(建议 here)是,如果我对标题行执行此操作,那么所有列标题将始终被读出...

【问题讨论】:

  • 您是否尝试过在运行时在 JS 中根据 ${show} 的值在 document.ready() 中添加标题行
  • FWIW,我怀疑 offscreen/1px 将是您在这里最好和最可靠的选择:关键是,否则您会要求屏幕阅读器做两件相互矛盾的事情:ignore 导航时的标题,但在查找标题时尊重标题。据我了解屏幕阅读器通常如何工作,他们要么将其视为存在,要么不存在,但不是这种类型的“两者”。这确实意味着屏幕阅读器用户将可以导航一个额外的“不可见”行,而视力正常的用户看不到,但与没有标签相比,这是一个较小的问题(并且可能是有用的上下文)。
  • 额外的可访问性提示:在这样的表格中,最好将每行中的初始单元格也设置为 TH - 即使您将其样式设置为看起来像常规 TD:这允许用户向下导航其他列,并在导航行时读出初始名称列。此外,将 scope="col" 放在顶部 TH 上,将 scope="row" 放在左侧 TH 上;如果没有这个,一些屏幕阅读器/浏览器组合会做奇怪的事情。

标签: html css html-table accessibility wai-aria


【解决方案1】:

如果 ChromeVox 目前是您唯一关心的问题,则使用 aria-hidden="false" 不会有什么坏处。您最好将它与 HTML5 隐藏属性结合使用(参见下面的示例),但其他技术也可以使用。有关不同技术的兼容性,请参阅 2013 年底的 this article。如果兼容性是一个问题,离屏方法似乎是要走的路。

离屏方法:

<style>
    thead {
        position:absolute;
        left:-9999px
    }
</style>

隐藏方法:

<table>
  <!-- ${show} is used to choose the right class the user configuration -->
  <thead hidden aria-hidden="false">
    <tr>
      <th>Name</th>
      <th>Value 1</th>
      <th>Value 2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John Doe</td>
      <td>Value 1a</td>
      <td>Value 2a</td>
    </tr>
  </tbody>
</table>

【讨论】:

    【解决方案2】:

    如果使用 opacity 0 而不是 Display None ,

    我试图用谷歌搜索任何明确的答案,但没有得到任何明确的答案,但我仍然可以假设屏幕阅读器会忽略不透明度并正常读取表格标签,而普通用户看不到它。

    【讨论】:

      【解决方案3】:

      我也对这里的答案感兴趣,希望我能理解这个问题。如果您使用&lt;colgroup&gt;&lt;col&gt; 标签并给它们一个aria-label 怎么办? ChromeVox 会读取它们,并且它们在语义上与列相关联。

      这是 jsfiddle 中的一个示例:http://jsfiddle.net/j87x7sn5/4/

      此代码使用同级选择器在标题可见时“隐藏”colgroups,并在不可见时“显示”它们,这样屏幕阅读器就不会读取它两次。

      【讨论】:

        【解决方案4】:

        而不是 display: none 在头上 - 尝试通过将其从流程中移出屏幕 - 类似于:

        <table class="hidden-header">
            ...
        
        .hidden-header thead {
            display: absolute;
            left: -9999
        }
        

        我还没有测试过这个......但可能会工作。

        编辑:进一步阅读:

        一个快速的谷歌游戏我推荐以下文章:

        您为什么不将此作为问题发送给 ShopTalk Show 的流行广播,以了解他们的其中一集?

        【讨论】:

        • 我很确定它不会起作用,因为屏幕阅读器中的 AFAIK 导航是基于 DOM 而不是基于可见的排列(这是我从开源代码中记得的,我甚至在我的问题结束时写了这个)。我明天上班再检查一下,可能我这里错了
        【解决方案5】:

        最简单的选项是从屏幕阅读器中隐藏标题行,方法是从 DOM 中删除它们(首选)或使用屏幕阅读器安全删除。然后使用text-indent: -999em; 或保留屏幕阅读器访问的类似视觉隐藏将标题插入每个适用的单元格。

        这是一个非常不令人满意的答案,但它应该与 jquery 站得住脚。大致:对于每个th,将内容存储在一个数组中,然后选择适用列中的每个 td,并选择 .prependTo() 'th'。

        再次,非常不满意和混乱,但我能想到的唯一万无一失的解决方案。祝你好运。

        【讨论】:

        • 我害怕这种答案,因为这并不完全正确;将这样的标签添加到每个单元格将意味着它们将始终被读出,而没有使它们静音的选项。您不需要听到每一行的列名,但您可能需要检查前几行...
        • 是的,我唯一的其他想法是更多开箱即用的想法。这些数据可以在表格之外提供吗? “John Doe 的值是 1a 和值 2a”也许你可以用几个介词/连接动词连接每条记录?
        【解决方案6】:

        这可能会对你有所帮助。

        <table>
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Value 1</th>
                            <th id="foo">Value 2</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>John Doe</td>
                            <td>Value 1a</td>
                            <td id="foo">Value 2a</td>
                        </tr>
                    </tbody>
                </table>
        
        
        #foo {
                visibility: collapse
            }
        

        但是关于上面提到的代码并没有所有的浏览器支持。

        为了改善你所拥有的,你可以在表格上使用table-layout: fixed,因为表格布局当表格单元格不是display: none时,它会自动display: table-cell

        【讨论】:

        • 我不确定我是否理解您的评论(我不想折叠一列,我想折叠一行)。无论如何,我尝试使用visibility: collapse(我将行的高度缩小到 1px 并删除了display: none)但效果不佳 - 屏幕阅读器确实浏览了折叠的单元格(说它们是空的),另外它没有将它们用作列标签。但是感谢您提出这个建议!
        猜你喜欢
        • 1970-01-01
        • 2017-11-23
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 2019-11-16
        • 2018-10-04
        • 1970-01-01
        • 2017-11-10
        相关资源
        最近更新 更多