jack jack - 7 months ago 22
HTML Question

What's an accessible way to group items within a radiogroup? (HTML5/WAI-ARIA)

I have a page I'm trying to code where the user has to select one from a number of options, presented as a grid of thumbnails. On similar pages, I've used

role="radiogroup"
and
role="radio"
(and appropriate scripting, labelling, etc), and that worked well - the difference with this one is that there are multiple sections within the larger radiogroup.

Edit, to clarify: I'd rather use native radio buttons, as several people have pointed out. I may not be able to because this is a big angular app with a lot of weird baggage I have to work around, but I'm looking into it. That said, whether they're
role="radio"
or
type="radio"
, my question is specifically about the best way to communicate that some of them are grouped together.

The user can pick only one option, from any of these sections. The structure is along these lines:




Choose an image

Artist 1


  • Image A

  • Image B



Artist 2


  • Image C

  • Image D






So basically, I'm looking for a way to preserve the "artist" context while moving through the image options. Something like
optgroup
from the
select
element. I've tried
fieldset
, which kind of works; I'm wondering if that's the best way to go?

Here's what I currently have, structure-wise. (Appropriate focus and keyboard management will be added as needed via JS.)

<form id="select-design" aria-label="Design Options">
<h2>Choose an image</h2>

<div role="radiogroup" id="collections-list" aria-label="Options" tabindex="0">

<fieldset id="group-1">
<legend>Artist: Jack Kirby</legend>

<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200/bada55/fff" alt="Cool Picture">
</div>

<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200/0de/fff" alt="Also Cool Picture">
</div>

</fieldset>

<fieldset id="group-2">
<legend>Artist: Kevin Maguire</legend>

<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200" alt="Nice Art">
</div>

<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200/0cd/fff" alt="Nicer Art">
</div>
</fieldset>

</div>




And here it is as a codepen.

One issue I'm seeing is that with my current html, it reads the first radio button as "2 of 3" - I guess it's treating the legend as a radioitem by default due to its placement in the DOM. Overall, it works, but I feel like it could be better.

Any thoughts?

Would be especially grateful if any screen-reader users can weigh in on this one.

Answer

Agree with @stringy about using native radio buttons (see first rule of ARIA use) But if you must create custom radio buttons you need to use the aria attribute aria-setsize on each control (also suggest looking at the accessible custom control checklist):

<fieldset id="group-1">
        <legend>Artist: Jack Kirby</legend>

        <div role="radio" aria-checked="false" tabindex="-1" aria-setsize="2">
            <img src="//placehold.it/200x200/bada55/fff" alt="Cool Picture">
        </div>

        <div role="radio" aria-checked="false" tabindex="-1" aria-setsize="2">
            <img src="//placehold.it/200x200/0de/fff" alt="Also Cool Picture">
        </div>

    </fieldset>

In regards to the outer <div> This in itself is not a radiogroup it groups 2 sets of radiogroups (which don't need to be specified using role=radiogroup as you are using fieldset/legend)

So suggest using role=group and removing the tabindex=0 as the div container isn't itself an interactive object and should not be in the focus order:

<div role="group" id="collections-list" aria-label="Options">

@jack if all radiobuttons are part of same group, then they should be containing within a single fieldset/legend or role=radiogroup with accessible name (via aria-label or aria-labelledby) then wrap each of the 3 sub groups in

<div role=group aria-label="whatever">
Comments