提问人:Charlie Taylor 提问时间:11/4/2023 最后编辑:Charlie Taylor 更新时间:11/13/2023 访问量:95
如何强制 Voiceover (MacOS) 正确读出美元金额,忽略内部跨度元素?
How can I force Voiceover (MacOS) to read out a dollar amount correctly, ignoring inner span elements?
问:
我有这个内容(简化):
<div>
$<span class="enlarged-text">245</span>.50
</div>
当我在 Safari (MacOS Monterey 12.7.1) 上使用 Voiceover 时(阅读下一个元素),它会根据需要将其读出为“二百四十五美元五十美分”。CAPSLOCK + Right
然而,使用画外音的自动读出功能 - 使用画外音启动 - 画外音会很奇怪地读出“两美元,四十五点五零”。有没有办法解决这个问题?CAPSLOCK + A
我已经在周围的 div 上尝试了未记录的内容,它有所帮助,但使用自动读数读出“二百四十五美元,五十”。使用它读作“二百四十五美元点五零”。role="text"
CAPSLOCK + Right
<div role="text">
$<span class="enlarged-text">245</span>.50
</div>
我还尝试将每件作品单独包围起来,但没有任何区别:span
<div role="text">
<span>$</span><span class="enlarged-text">245</span><span>.50</span>
</div>
答:
由于您在使用 Voiceover 的自动读出功能时遇到不一致的行为,请尝试使用该属性显式指定 Voiceover 应读出的文本(ARIA:可访问的富 Internet 应用程序)。aria-label
<div aria-label="245 dollars and 50 cents">
$<span class="enlarged-text">245</span>.50
</div>
您还可以使用 aria-hidden
属性来隐藏导致屏幕阅读器读出不正确的元素,并添加包含屏幕阅读器正确格式的视觉隐藏。span
<div>
<span aria-hidden="true">$<span class="enlarged-text">245</span>.50</span>
<span class="visually-hidden">245 dollars and 50 cents</span>
</div>
.visually-hidden
是一个类,它在视觉上隐藏内容,但使屏幕阅读器可以访问它。
它将被定义为:
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
(摘自“CSS in Action / Invisible Content Only for Screen Reader Users”(CSS在行动/仅供屏幕阅读器用户使用的不可见内容)")
您也可以尝试将 CSS 属性与 ::before
或 ::after
伪元素一起使用来注入货币符号,这可能不会干扰 Voiceover 的读出逻辑。content
<div class="price">
<span class="enlarged-text">245</span>.50
</div>
.price::before {
content: "$";
}
属性,并且仅适用于交互式/可聚焦元素和地标,或具有此类角色的元素。因此,在这种情况下,它将不起作用。
aria-label
aria-labelledby
实际上,有时可以在非交互式元素上使用以提供可访问的名称,但其支持在不同的屏幕阅读器和方案中确实可能不一致。aria-label
目标仍然是确保屏幕阅读器正确地将美元金额解释为整数后跟美分,而不会被 HTML 结构误导。
您可以尝试将美元符号和数字组合在一个没有视觉空间的单个中,然后使用 CSS 在视觉上仅放大美元金额部分。span
<div>
<span aria-hidden="true" class="price">$245<span class="cents">.50</span></span>
<span class="visually-hidden">245 dollars and 50 cents</span>
</div>
.price .cents {
font-size: smaller;
}
或者,如果无法修改视觉外观,则可以使用 JavaScript 在页面加载或内容更改时根据跨度的内容动态设置属性。aria-label
window.onload = function() {
var priceDiv = document.querySelector('.price-container');
var price = priceDiv.innerText;
priceDiv.setAttribute('aria-label', price.replace('$', '') + ' dollars and ' + price.split('.')[1] + ' cents');
};
<div class="price-container" role="text">
$<span class="enlarged-text">245</span>.50
</div>
JavaScript 方法动态操作,确保标签始终设置为需要读出的正确美元金额。aria-label
如果由于 Voiceover 的特定怪癖,上述解决方案都不起作用,请按照 QuentinC 的建议检查是否有任何现有的 CSS 规则干扰屏幕阅读器正确解释内容的能力。
很遗憾,我宁愿拥有视觉和屏幕阅读器用户都能阅读的一个元素。否则,内容很容易不同步。
为了降低内容不同步的风险,您可以使用 JavaScript 根据可见内容动态更新视觉上隐藏的文本。
这样,对可见价格的任何更改都会自动反映在屏幕阅读器文本中。
除了可见内容外,还使用视觉上隐藏的跨度。
<div id="price-container">
$<span class="enlarged-text">245</span>.50
<span class="visually-hidden" id="accessible-price"></span>
</div>
确保屏幕阅读器可以访问它,但不可见。
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
动态设置视觉上隐藏的跨度的内容。
function updateAccessiblePrice() {
var priceText = document.getElementById('price-container').innerText;
var accessiblePrice = priceText.replace('$', '') + ' dollars and ' + priceText.split('.')[1] + ' cents';
document.getElementById('accessible-price').innerText = accessiblePrice;
}
// Initial update
updateAccessiblePrice();
// Update when the content changes (e.g., via AJAX, user action, etc.)
// That needs to be triggered appropriately depending on how your content updates
这种方法将确保屏幕阅读器文本始终与可见文本同步。
它需要一些额外的努力来设置,但它有效地解决了保持屏幕阅读器阅读的内容和视力正常的用户看到的内容之间的一致性的问题。
评论
使用 JavaScript,你可以让它有点动态,但一点也不完美
window.onload = function() {
var priceDiv = document.querySelector('.price-container');
var price = priceDiv.innerText;
priceDiv.setAttribute('aria-label', price.replace('$', '') + ' dollars and ' + price.split('.')[1] + ' cents');
};
评论