Devographics / Monorepo

Monorepo containing the State of JS apps
surveyform-sigma.vercel.app
Other
127 stars 52 forks source link

Survey: radio buttons do not have group labels because of invalid HTML #307

Closed aardrian closed 1 year ago

aardrian commented 1 year ago

While the radio buttons live within a fieldset/legend construct, it is not being conveyed as expected because the construct is invalid HTML.

Using Firefox 117 with NVDA 2023.2, as I moved into each set of radio buttons I expected to hear the group label (anticipating it was the heading for the box). I did not.

This is the elided HTML showing the <legend> construct:

<fieldset>
 <div>
  <legend class="form-label-legend">
   <h3 class="form-label-heading" id="datalist_element">
    <label class="form-label" for="html2023__features__datalist_element__experience">
     <span class="entity-label">
      <code>&lt;datalist&gt;</code>
     </span>
    </label>
    <div class="add-to-list add-to-list-notInlLst">
     <span class="icon-wrapper ">
      <button type="button" class="btn btn-primary">
       […]
       <span class="sr-only">Add to Your Reading List</span>
      </button>
     </span>
    </div>
   </h3>
  </legend>
[…]
 </div>
</fieldset>

A <label> and a <button> nested in the <h3> nested in the <legend> is unnecessarily complex.

The fix, however, is straightforward. Move the <legend> to be a direct child of <fieldset>. The intervening <div> is breaking the association. The current construct is invalid HTML since <legend> must be "the first child of a fieldset element" (see the WHATWG HTML spec).

I have made a video to show this bug in action. As a screen reader user moves from one set of radios to the next, there is no context provided for what the radios are addressing. See it happen at 0:02 and 0:21.

https://github.com/Devographics/Monorepo/assets/1376607/0f9d58fa-2aaf-4c97-9ca7-23e1c024f57f

SachaG commented 1 year ago

Move the to be a direct child of

.

That's easy enough! Thanks for the suggestion!

SachaG commented 1 year ago

Removing the

Now I'm wondering whether the question title ("Years of Experience", "Age", etc.) should be a label in the first place… Depending on the form input type, sometimes it's the <legend>, but sometimes it's a <label> for the input.

For example, comparing these two:

Here "Years of Experience" can be a legend, and we can reserve labels for "Less than one year", "1 to 2 years", etc.

Screenshot 2023-09-24 at 7 21 18

But is it safe to do the same thing here? Is it ok to just not have a label at all for the number input?

Screenshot 2023-09-24 at 7 21 31
aardrian commented 1 year ago
SachaG commented 1 year ago

Is there any way to keep a consistent markup structure between the different question types? What if we added a hidden <label> for the Age input?

aardrian commented 1 year ago

Two questions, so two answers:

  1. Why?
  2. What is that meant to address?
SachaG commented 1 year ago
  1. Just to keep things consistent and make sure we don't introduce any styling or behavior inconsistencies between questions.
  2. I was thinking not having a label might be a issue from an a11y standpoint.

That being said if conditionally making the headings legends or labels based on the input type really is the best solution, I can implement it.

aardrian commented 1 year ago
  1. Gotcha. To me, that is a CSS issue. The HTML should not be influenced by that, while CSS can visually give these two different elements consistent styling. And there should be behavior differences between questions of different types. Radios are not the same as text boxes either by [edited to fix typo] interaction type or information gathered.
  2. Since a single label should only be associated with a single field, the issues are not associating them, having too many, or having none.

If you post pseudo-code of what you are thinking, that might help my mental model.

SachaG commented 1 year ago

OK, then it sounds like the best solution would be having some kind of headingAsLabel={true} prop on inputs that require it.

aardrian commented 1 year ago

I appreciate the pseudo-code. That, sadly, is meaningless to me. I only speak HTML; all those fancy moon languages are lost on me. Probably years of moving from client to client where the only consistent language was HTML.