Screen reader 阅读了所有内容,但没有跳转到它

Screen reader reads it all, but does not tab to it

所以我有一个 react-redux 电子商务应用程序,但我在弄清楚如何让屏幕 reader 从付款部分转到订单摘要组件时遇到问题订单摘要。

现在,如果我单击 table 的订单摘要内容,包括 h4 header,屏幕 reader 会读取它,但我无法通过 Tab 键切换到它来自付款部分。

这是 OrderSummary.js 文件:

    <h2 className="title h3">Order Summary</h2>
              <table className="subtotal-wrapper body-color">
                <caption className="screen-reader-text">Order Summary</caption>
                <tbody>
                  <tr>
                    <th>Subtotal:</th>
                    <td>${formatPrice(this.props.orderSummary.originalSubtotal)}</td>
                  </tr>
                  {showShippingCost(this.props.orderSummary.totalShippingCost, this.props.orderSummary.totalShippingDiscount)}
                  <tr>
                    <th>Est Sales Tax:</th>
                    <td>${formatPrice(this.props.orderSummary.totalEstimatedTax)}</td>
                  </tr>
                  {getOptionalComponent('Total Savings:', this.props.orderSummary.discountedSubtotal)}
                </tbody>
              </table>

因此,当使用 Tab 键时,ChromeVox 和 VoiceOver 将从 Address.js 组件中的这种形式开始:

<form className="marketing-offer" onSubmit={doNothing} >
              <Checkbox
                name="marketingOptIn"
                checked={!!this.props.marketingOptIn}
                onChange={this.props.handleMarketingOptInChange}
              >
                <span className="payment-option special-offers">Yes! I would like to receive updates, special offers, and other information from shopDisney and The Walt Disney Family of Companies.</span>
              </Checkbox>
            </form>

直接点击继续查看订单汇总按钮,完全跳过OrderSummary.js中的table。

如果我故意点击它,它确实会读取它,但它不会像我希望的那样从 Address.jsOrderSummary.js 内表单字段中的复选框切换。

我该如何解决这个问题?

尝试在所有 html 元素上添加 tabindex="1"、tabindex="2" 等。

将 tabindex="0" 设置为要按 Tab 键顺序排列的元素将解决此问题。 tabindex="0" 将根据源代码中的位置以 Tab 键顺序添加每个元素。默认情况下,只有 interactive elements 被放入 Tab 键顺序。

尽管作为注释,不建议将非交互元素添加到 Tab 键顺序中:https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex#Accessibility_concerns

使用 0 的 tabindex 而不是正数是很好的建议,但正如@CodyS 在他的 post 末尾提到的那样,将 non-interactive 元素放入 Tab 键顺序非常气馁。

如果您担心屏幕 reader 用户找不到 table 或无法阅读它,如果您的页面组织良好,这应该不是问题。 "well organized",我的意思是部分在逻辑上与适当的 <nav><section> 和其他 document structure 元素分组,您可以适当使用标题(<h1><h2>, 等等),并且你的 table 格式正确 (<th scope="col">)。这样做意味着屏幕 reader 用户可以使用特殊的导航快捷键来查找所有这些元素并获得页面布局的概览。

既然你提到了 tables,请确保你有明确定义的列 headers (<th scope="col">) 还有 行 headers (<th scope="row">)。行 header 经常被忽视,但在使用屏幕 reader 浏览 table 时它们非常有用。如果我在 table 中间的单元格中,并且我垂直向下导航该列 (ctrl+alt+downarrow with a screen reader), 然后我会听到单元格值但可能不知道单元格值与什么相关联。如果您有行 header,那么行 header 将在宣布单元格值之前宣布,并为单元格提供上下文。 table 中的第一列通常用作行 header,即使它只包含值。像这样:

<table>
  <tr>
    <th scope="col">Name</th>
    <th scope="col">Age</th>
    <th scope="col">Favorite Color</th>
  </tr>
  <tr>
    <th scope="row">Jane</th>
    <td>35</td>
    <td>Red</td>
  </tr>
  <tr>
    <th scope="row">Mary</th>
    <td>36</td>
    <td>Blue</td>
  </tr>
  <tr>
    <th scope="row">Cindy</th>
    <td>37</td>
    <td>Green</td>
  </tr>
</table>

如果我的屏幕 reader "focus" 显示为 35 并且我向下移动了一个单元格,我会听到 "Mary 36" 而不仅仅是“36”并且会知道 36 指的是玛丽.

当你谈到从 "payment" 部分移动到 "order summary" 部分时,如果这两个部分完全有一个 <section> 元素,那么屏幕 reader 用户可以按 landmarks 导航并轻松找到不同的部分。

<section aria-label="payment options">
  ...
</section>
<section aria-label="summary of order">
  ...
</section>

aria-label 将被屏幕读取 reader 但不会在屏幕上显示。