尽管屏幕尺寸会更改功能,但如何在组件中保持良好的可访问性?

发布于 2025-01-24 11:37:28 字数 1202 浏览 3 评论 0原文

我目前正在构建一个由三个无序列表组成的响应组件,每个列表都有相关的标题。该代码看起来像这样:

<div>
  <section aria-labelledby="heading1">
    <h3 id="heading1" data-state="open">Heading 1</h3>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </section>
  <section aria-labelledby="heading2">
    <h3 id="heading2" data-state="open">Heading 2</h3>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </section>
  <section aria-labelledby="heading3">
    <h3 id="heading3" data-state="open">Heading 3</h3>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </section>
</div>

在较大的屏幕上,CSS将其作为三列和较小的屏幕呈现,它变成了手风琴,单击标题将切换相邻列表的显示。打开/关闭功能由JavaScript处理,只需在打开和关闭之间打开数据状态即可。

这一切都很好,但是当涉及到可访问性时,我有点困难。我想与辅助技术进行交流,即标题是按钮(使用角色=“按钮”,或通过将标题文本包裹在按钮元素中),但这只有在作为手风琴显示时才正确。在三列模式下,标题不应是按钮,只是标题。

任何帮助将不胜感激!

I'm currently building out a responsive component comprised of three unordered lists, each with an associated heading. The code looks something like this:

<div>
  <section aria-labelledby="heading1">
    <h3 id="heading1" data-state="open">Heading 1</h3>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </section>
  <section aria-labelledby="heading2">
    <h3 id="heading2" data-state="open">Heading 2</h3>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </section>
  <section aria-labelledby="heading3">
    <h3 id="heading3" data-state="open">Heading 3</h3>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>
  </section>
</div>

On larger screens, the CSS renders this as three columns and on smaller screens, it turns into an accordion where clicking on a heading will toggle the display of the adjacent list. The open/close functionality is handled by Javascript and simply toggles the data state between open and closed.

This is all working fine, but when it comes to accessibility I'm a little stumped. I'd like to communicate to assistive technology that the headings are buttons (either using role="button" or by wrapping the heading text in a button element) but this would only be correct when displaying as an accordion. In three-column mode, the headings should not be buttons, just headings.

Any help would be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奈何桥上唱咆哮 2025-01-31 11:37:28

所以DOM保持不变?在响应视图中没有添加其他HTML元素?

如果是这样,那有点棘手,但可能您可以使用“模式,然后在完全屏幕模式下调整元素上的属性。

Accordions consist of:

  • The accordion element – A collection of panels contained within an outer pane (often a list)
  • Accordion header – The labeled area(s) of the accordion panel that are expandable and collapsible
  • Accordion panel – The area (container) that contains the content specific to each header

The title of each accordion header is contained in a

每个手风琴标头按钮都包裹在&lt; hx&gt;元素中,其级别适合页面的信息体系结构。按钮元素是标题元素内部的唯一元素。

如果可见与手风琴标头关联的手风琴面板,则标头按钮元素的aRIA扩展将设置为“ true” 。如果面板不可见,则ARIA扩展将设置为“ false” 。面板本身应具有ARIA隐藏适当设置或使用CSS隐藏(display:none)。

手风琴面板具有prole =“ region”aria-labelledby,其值指的是控制面板显示的按钮。

这非常接近您发布的代码。您的列表中有一个容器(&lt; Section&gt;),其中具有 region>区域 的默认角色,您通过将其指向标题来标记该部分。

因此,一旦拥有手风琴代码,就可以在显示只是一个简单的三列列表时确定不需要该结构的哪些部分。

<!-- main accordion container -->
<div>
  <h2>
    <button aria-expanded="false" id="accordion1id">first accordion section</button>
  </h2>  
  <section aria-labelledby="accordion1id">
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
  <h2>
    <button aria-expanded="false" id="accordion2id">second accordion section</button>
  </h2>  
  <section aria-labelledby="accordion2id">
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
</div>

这确实接近您的原始代码。当您只需要列表结构(桌面视图)时,您应该能够在所有roun =“呈现”中添加到所有&lt; button&gt; elements extress&gt; emements> “其中的元素,从本质上将它们变成纯文本,因此您剩下的就是带有儿童文字的标题。屏幕阅读器只会知道有一个标题,然后是带有嵌入式列表的部分。

您也应该从按钮中删除ARIA扩展的,因为该属性仅在按钮上有效而不是纯文本元素。

如果愿意,还可以在&lt; e节上删除aria-labelledby,然后将删除 landmark 这些元素的角色,因此屏幕读取器也会忽略它们。 The code would look something like this:

<!-- main accordion container -->
<div>
  <h2>
    <button role="presentation" id="accordion1id">first accordion section</button>
  </h2>  
  <section>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
  <h2>
    <button role="presentation" id="accordion2id">second accordion section</button>
  </h2>  
  <section>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
</div>

What the screen reader sees will effectively be:

<div>
  <h2>
    first accordion section
  </h2>  
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>    
  <h2>
    second accordion section
  </h2>  
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>    
</div>

Update

Thanks, @Robin, you are correct. ARIA属性仅是提示的辅助技术,并且不会影响行为,因此添加角色=“呈现”&lt;按钮&gt;,虽然它确实使按钮不再以按钮宣布,但这并不能阻止用户对其进行表达或单击它,因此您需要tabindex =“ - 1” < /代码>在按钮上以防止选项卡,您需要将按钮上的事件处理为NO-OPS。您可能还需要应用CSS,以使该按钮看起来也不像按钮。这都是可行的,但有时更容易交换和分离不同的组件。

So the DOM stays the same? No additional HTML elements are added in responsive view?

If so, then that's a little tricky but potentially you could work with the Accordion Design Pattern and then tweak the properties on the elements when it's in fullscreen mode.

Accordions consist of:

  • The accordion element – A collection of panels contained within an outer pane (often a list)
  • Accordion header – The labeled area(s) of the accordion panel that are expandable and collapsible
  • Accordion panel – The area (container) that contains the content specific to each header

The title of each accordion header is contained in a <button> or an element with role="button".

Each accordion header button is wrapped in an <hX> element with a level that is appropriate for the information architecture of the page. The button element is the only element inside the heading element.

If the accordion panel associated with an accordion header is visible, the header button element has aria-expanded set to "true". If the panel is not visible, aria-expanded is set to "false". The panel itself should have aria-hidden set appropriately or hidden with CSS (display:none).

The accordion panel has role="region" and aria-labelledby with a value that refers to the button that controls display of the panel.

This is very close to the code you posted. You have a container for your list (<section>) which has a default role of region and you are labeling that section by pointing it to the heading.

So once you have the accordion code, then you can decide what parts of that structure are not needed when the display is just a simple three column list.

<!-- main accordion container -->
<div>
  <h2>
    <button aria-expanded="false" id="accordion1id">first accordion section</button>
  </h2>  
  <section aria-labelledby="accordion1id">
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
  <h2>
    <button aria-expanded="false" id="accordion2id">second accordion section</button>
  </h2>  
  <section aria-labelledby="accordion2id">
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
</div>

This is really close to your original code. When you only need the list structures (desktop view), you should be able to add role="presentation" to all the <button> elements which removes the "buttonness" of the elements and essentially turns them into plain text so all you're left with is a heading with child text. A screen reader will only know there is a heading followed by a section with an embedded list.

You should remove aria-expanded from the buttons too since that attribute is only valid on a button and not a plain text element.

If you wanted, you could also remove the aria-labelledby on the <section> and that would remove the landmark role for those elements so they'll be ignored by screen readers too. The code would look something like this:

<!-- main accordion container -->
<div>
  <h2>
    <button role="presentation" id="accordion1id">first accordion section</button>
  </h2>  
  <section>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
  <h2>
    <button role="presentation" id="accordion2id">second accordion section</button>
  </h2>  
  <section>
    <ul>
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
    </ul>    
  </section>
</div>

What the screen reader sees will effectively be:

<div>
  <h2>
    first accordion section
  </h2>  
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>    
  <h2>
    second accordion section
  </h2>  
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>    
</div>

Update

Thanks, @Robin, you are correct. ARIA attributes are only hints to assistive technology and don't affect the behavior so adding role="presentation" to the <button>, while it does make the button not announce as a button anymore, that doesn't prevent a user from tabbing to it or clicking on it so you'd need tabindex="-1" on the button to prevent tabbing and you'd need to handle events on the button as NO-OPs. You also might need to apply CSS so the button doesn't look like a button either. That's all doable but is sometimes easier to just swap in and out different components.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文