如何可访问地隐藏表格标题元素?

时间:2019-02-26 00:55:01

标签: html css accessibility voiceover

有什么方法可以隐藏表格标题,而又不会破坏屏幕阅读器解释表格其余部分的方式?用通常推荐的样式隐藏<caption>来隐藏元素在视觉上会破坏VoiceOver的行为,从而导致在使用“下一个”按键线性阅读时,它会跳过表中的最后一行。 (可以通过显式向下导航到列来将VoiceOver强制到最后一行,但这需要用户知道这样做。)

我认识到这可能是VoiceOver本身的错误,但是如果有一个干净的解决方法,那将是理想的,因为WCAG需要使用实际可用的辅助技术进行辅助操作。

这是一个极简的例子来演示:

更新:以下样式规则是Magento框架中用于在视觉上隐藏元素,同时使屏幕阅读器可以访问它们的标准规则。导致VoiceOver行为的关键规则是position: absolute;但是,如果仅将其删除,则会影响布局流程。

caption {
    border: 0;
    clip: rect(0, 0, 0, 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
}
<table>
  <caption>Table of Fruits</caption>
  <thead>
    <tr>
      <th>Fruit</th>
      <th>Color</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Apple</td>
      <td>Red</td>
    </tr>
    <tr>
      <td>Pear</td>
      <td>Green</td>
    </tr>
  </tbody>
</table>

<p>Voiceover will jump straight from "Red" in prior table to this paragraph, skipping the last row.</p>

3 个答案:

答案 0 :(得分:1)

一些差异

<th> Needs <tr> as a Parent to be Valid

OP O 原始 P ost)代码在<tr>中没有<thead>这可能是最后一个<tr>被跳过的原因。无效的HTML易于混淆诸如 VoiceOver 之类的应用程序。


三种方法

  

免责声明:未经测试- Caveat Emptor

以下演示包含三个<table>s,它们具有相同的HTML标记,CSS规则和文本内容。每个<caption>都有一个不同的.class,它们使用一种隐藏内容的特定方法:

  1. .clipped -假定剪辑内容需要一定的长度:clip: rect(0, 0, 0, 0);看起来很可疑。其他一些属性和值似乎也是临时的,因此请尝试将caption {...}规则集替换为:

    .clipped {
      position: absolute !important;
      height: 1px; 
      width: 1px; 
      overflow: hidden;
      clip: rect(1px, 1px, 1px, 1px);
    }  
    
  2. .transparent -这只是为文本分配透明颜色。高度仍然存在( VoiceOver 要求),但是可以根据需要进行调整。 opacity: 0也是一种选择,但是在某些情况下,opacity: 0被认为与visibility: hidden相同( VoiceOver 会忽略)。

    .transparent {
      color: rgba(0, 0, 0, 0);
    }  
    
  3. .collapsed -折叠元素的内容但保留其高度,以便 VoiceOver 可以识别它。

    .collapsed {
      visibility: collapse;
    }
    

演示

table {
  border: 1px solid #000;
  table-layout: fixed;
  border-collapse: collapse;
  min-width: 200px;
}

th,
td {
  width: 50%;
  border: 1px solid #000;
}

.clipped {
  position: absolute !important;
  height: 1px; 
  width: 1px; 
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
}

.transparent {
  color: rgba(0, 0, 0, 0);
}

.collapsed {
  visibility: collapse;
}
<table>
  <caption class='clipped'>CAPTION</caption>
  <thead><tr><th>TH</th><th>TH</th></tr></thead>
  <tbody><tr><td>TD</td><td>TD</td></tr>
  <tr><td>TD</td><td>TD</td></tr></tbody>
</table>

<table>
  <caption class='transparent'>CAPTION</caption>
  <thead><tr><th>TH</th><th>TH</th></tr></thead>
  <tbody><tr><td>TD</td><td>TD</td></tr>
  <tr><td>TD</td><td>TD</td></tr></tbody>
</table>

<table>
  <caption class='collapsed'>CAPTION</caption>
  <thead><tr><th>TH</th><th>TH</th></tr></thead>
  <tbody><tr><td>TD</td><td>TD</td></tr>
  <tr><td>TD</td><td>TD</td></tr></tbody>
</table>

<p>The <abbr title="Original Post"><b>OP</b></abbr> code didn't have a <code>&lt;tr&gt;</code> in the <code>&lt;thead&gt;</code> which could be the reason why the last <code>&lt;tr&gt;</code> is being skipped.</p>

答案 1 :(得分:0)

好吧...我看到您使用caption标签只是为了辅助功能,这意味着您不想以视觉方式显示它。我建议不要使用它,而应在table标签中使用aria-label,这将使其可供屏幕阅读器使用。

<table aria-label="Table of fruits"> ... </table>

阅读此page的第一段,以了解关于aria-label的用法。

答案 2 :(得分:0)

由于引起问题的原因是position: absolute;,因此务实的解决方案是跳过它,而使用margin-top: -1px;。经过测试和验证的i Chrome +画外音。

.clipped {
  position: absolute !important;
  height: 1px; 
  width: 1px; 
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
}