英文:
In case of a Fieldset that is nested inside a Fieldset - how should the Legends be accessible to screenreaders?
问题
我正在处理公司的遗留代码,其中有多个字段集(Fieldset)位于其他字段集内部。它们必须符合屏幕阅读器的可访问性要求,其中发现的一个问题是第一个字段集的标题(Legend)未被传达为与单选按钮的标签相关联。
这是Django环境的一部分 - 它是嵌套自定义模板标签的一部分,可能会更改最深层字段集内的嵌套表单,但似乎不可能尝试将最高字段集的值传递到嵌套组件中,但目前,这个问题集中在检查表单是否实际上是正确的HTML。
我知道的事情:
- 一些屏幕阅读器不会读取标题(Legend),因此必须在每个输入标签的
<span>
中重复标题,并使用仅供屏幕阅读器使用的类。 - 但是:不应该仅仅重复整个标题文本,而是使用一个不会在屏幕阅读器读取时让人感到烦扰的简短描述。
那么,这段代码是否正确?
- 所有那些
sr-only
的<span>
是否完全不必要? - 在Django模板中,我只是使用最深字段集的标题文本作为一个变量,然后可以在每个标签的
<span>
中使用它,并且我将其保持简短并称之为'Answer'。'Answer'是否实际上是一个良好的用于可访问性的标题文本,还是太通用了?
我只是不确定如何处理某些屏幕阅读器会读取标题而其他屏幕阅读器不会的情况 - 或者我们应该只是使用aria-label
?
英文:
I am working on a company's legacy code that has multiple instances where Fieldsets are inside of other Fieldsets. They have to adhere to accessibility for screen-readers and one of the issues that was found, is that the Legend of the first Fieldset, is not communicated as being related to the Labels of the radio buttons.
This is part of a Django environment - it is part of nested custom template-tags and it's possible to change the nested Form inside the 'lowest/deepest' Fieldset, but seems impossible to try and pass the value of the highest Fieldset down to the nested componentns, but for now: this question concentrates on checking to see if the form is actually correct HTML.
Things I know:
- Some screen-readers do not read out the Legends, and therefor you have to repeat the Legend for each input Label in a span with a screen-reader only class.
- but: you are not supposed to simply just repeat the entire Legend text for each input, but instead use a short description that isn't too annoying when screenreaders read it.
Would this code be correct then?
- Or are all of those sr-only spans
completely unnecessary? - In the Django template I'm simply using the
deepest Legend text as a variable that then can be used in the spans
of each Label, and I have kept it short and called it 'Answer'. Is
'Answer' actually a good Legend text for accessibility or is it too
generic?
I'm just not sure how to account for situations where some screenreaders will read the Legend, and others wont - or should we just use aria-label instead?
<h1 class="h1">
</h1>
<p class="p">Answer these questions for help from the municipality.</p>
<aside class="step-indicator" aria-label="Step indicator">
<ol class="step-indicator__list">
<li class="step-indicator__list-item step-indicator__list-item--completed P" data-step="1" aria-label="completed"><a href="/what-is-your-situation" class="link" aria-label="Situation"><span class="link-step__text">Situation</span></a></li>
<li class="step-indicator__list-item step-indicator__list-item--active P" data-step="2" aria-current="step" aria-label="current step"><a href="/what-is-your-situation/how--would-you-like-to-gain-experience" class="link" aria-label="Job experience"><span class="link__text">Job experience</span></a></li>
</ol>
</aside>
<fieldset class="questionnaire__fieldset">
<legend class="h4" id="question">In which way would you like to gain job experience?</legend>
<p class="p">Choose the answer that suits you best</p>
<form class="form" method="POST" action="/what-is-your-situation/how--would-you-like-to-gain-experience" id="questionnaire_step">
<input type="hidden" name="csrfmiddlewaretoken" value="999999999999x">
<div class="form__control">
<fieldset class="form__stack">
<legend>Answer</legend>
<div class="radio">
<input class="radio__input" type="radio" name="answer" value="5" id="id_answer_1"><label class="radio__label" for="id_answer_1"><span class="sr-only">Answer</span>I want to try and see if a job suits me.</label>
</div>
<div class="radio">
<input class="radio__input" type="radio" name="answer" value="6" id="id_answer_2"><label class="radio__label" for="id_answer_2"><span class="sr-only">Answer</span>I want to do volunteerwork</label>
</div>
</fieldset>
</div>
<input type="hidden" name="csrfmiddlewaretoken" value="999999999999x">
<div class="form__actions ">
<a class="button button--textless button--icon button--icon-before" href="/what-is-your-situation" title="Previous" aria-label="Previous">
<span aria-hidden="true" class="material-icons ">arrow_backward</span>Previous</a>
<button class="button button--textless button--icon button--icon-after button--primary" type="submit" name="" value="" title="Next" aria-label="Next">
<span aria-hidden="true" class="material-icons ">arrow_forward</span>Next</button>
</div>
</form>
</fieldset>
</div>```
</details>
# 答案1
**得分**: 2
通常情况下,只要使用语义化的HTML元素,你不需要担心不同屏幕阅读器如何宣读内容。在这种情况下,嵌套的<fieldset>/<legend>元素是完全有效的,尽管一些屏幕阅读器只会宣读内部元素的嵌套标题,但其他屏幕阅读器会将内部和外部标题连接在一起。这实际上是由屏幕阅读器供应商决定的。不要试图编写代码来调整宣读方式。
当我使用你的示例代码时,JAWS和NVDA都在我按<kbd>tab</kbd>键到第一个单选按钮时宣读了两个标题。它们的宣读几乎完全相同。
JAWS
“你想以哪种方式积累工作经验?组
答案组
答案 我想试试看是否适合我的工作。单选按钮,未选中,总共2个”
NVDA
“你想以哪种方式积累工作经验? 分组
答案 分组
答案 我想试试看是否适合我的工作。单选按钮,未选中,总共2个”
当我切换到第二个单选按钮时,我**不**再听到内部标题,因为我已经知道我在一个“组”内。
一些屏幕阅读器在你离开一个“组”(fieldset)时会宣读,而其他一些则不会。而且一些屏幕阅读器允许你通过“冗余”设置进行自定义。
如果我的键盘焦点在所有字段集之后,然后我向后按Tab键到最后一个单选按钮,外部和内部字段集将再次被宣读。
我建议**不要**在你的单选按钮上添加额外的“sr-only”文本以强制宣读标题,因为在一些屏幕阅读器上,你将同时听到你的“sr-only”文本和标题文本,这会导致重复宣读。
总之,你不应该需要做任何额外的工作。只需正确嵌套你的字段集,让屏幕阅读器完成其工作即可。
<details>
<summary>英文:</summary>
In general, you should not worry about how different screen readers announce things **provided you are using semantic HTML elements**. In this case, nested \<fieldset>/\<legend> elements are perfectly valid even though some screen readers will announce only the nested legend for the inner elements but other screen readers will concatenate the inner and outer legends. That's really a decision for the screen reader vendor. Don't try to code around how things are announced.
<fieldset>
<legend>legend 1</legend>
...form elements...
<fieldset>
<legend>inner fieldset</legend>
...form elements...
</fieldset>
...form elements...
</fieldset>
When I use your sample code, both JAWS and NVDA read both legends when I <kbd>tab</kbd> to the first radio button. They both announce almost exactly the same.
JAWS
"In which way would you like to gain job experience? group
Answer group
Answer I want to try and see if a job suits me. radio button, not checked, 1 of 2"
NVDA
"In which way would you like to gain job experience? grouping
Answer grouping
Answer I want to try and see if a job suits me. radio button, not checked, 1 of 2"
When I tab to the second radio button, I do **not** hear the inner legend again because I already know I'm in a "group".
Some screen readers will announce when you leave a "group" (fieldset), others don't. And some let you customize it via the "verbosity" settings.
If my keyboard focus were after all the fieldsets and then I tabbed backwards to the last radio button, the outer and inner fieldsets would be announced again.
I would recommend **not** having all the extra `sr-only` text on your radio buttons to force the legend announcement because with some screen readers, you'll hear your sr-only text **and** the legend text, so it'll be duplicated.
In summary, you shouldn't have to do any extra work. Just nest your fieldsets correctly and let the screen reader do its thing.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论