Page MenuHomePhabricator

Inlined help needs to be part of widget's `<label>` element
Closed, DeclinedPublic


The inlined labels are currently, as of v0.27.3, residing in their own <label> element.
Not only is the label not connected (via for attribute) to the input currently, it should probably better be added as span element to the main label and styled as block element as in current layout.

Two labels even with for are fine from HTML validation perspective, but in the past, screenreaders (specifically NVDA) have ignored the second one.

Related Objects

Event Timeline

This sounds like a good DOM structure, but we might need to figure out how to do this correctly.

Currently, by using LabelWidget we get some complex functions like setLabel and setLabelContent for free. But, LabelWidget enforces the <label> element (as it should) and overrides whatever you may pass in the $label config.

Also if we force any content — <span> or otherwise — into the main label, we'll have to make sure we keep adding it even when the developer explicitly uses the setLabel method on just the label. This might be tricky, and also a bad experience for the devs themselves.

One solution might be to have subLabel be a config of the LabelWidget itself and use that directly from FieldLayout or wherever else. But that would be a bigger change than what we started out with. @matmarex what do you think?

@Volker_E suggested in a meeting that we could use a <small> tag too (instead of <span>). It doesn't make a difference to the screen-readers (yet), but would be more semantic.

Makes sense to me.

@Prtksxna Yeah, from my short research and tests it's not fully clear how strong the support for <small> is, but the element is intended to imply a de-emphasized meaning, so we should go with it.

I don't think this is going to be feasible if we want to have reasonable control over the position of the help label (for example putting more out of the way after the field).

It think we should just ass the second for attribute.

The problem statement was, that the screenreader in question, NVDA, ignored a second label and didn't expose it to the user. One label would definitely resolve that in any combination.

NVDA, ignored a second label

I assumed this meant ignored it as a field label, but the help text isn't the same as the label, to it's up to the screenreader to decide when it is best to give this info the user. Arguably pushing the user listen to the entire (potentially very long) help text before advancing them to the field is not a good experience either. In addition it severely restricts our visual layout, which affects 99.9% of users.

The user doesn't have to listen to (they always can move focus as soon as they think they get the meaning), but in the other way (two labels) they simple don't get the label read out as connected to the input.
And it is meant as a label describing the input in our own logic, why would you argue for a for attribute then?!

With two label elements in the DOM above we also don't have enough reasonable control over the position, what are we arguing here for?

With two label elements in the DOM above we also don't have enough reasonable control over the position, what are we arguing here for?

I don't understand? I'm saying we shouldn't force ourselves to have both the label and the help text inside the same DOM node.

I'm with Ed here:

  • The help text is additional and it should not be part of the main label. Visual users should not have to read it before they can fill in the field, and it should not be read out to screenreader users before they can fill in the field. For screenreader accessibility, maybe we should instead use aria-describedby to point to the inline help (as we already use it for the popup help):

The aria-labelledby attribute is similar to the aria-describedby in that both reference other elements to calculate a text alternative, but a label should be concise, where a description is intended to provide more verbose information.

  • If we move the inline help under the field (T197004), which seems like a good idea to me given the above, it becomes impossible to put it into one <label> element with the main label anyway…

Prepared this yesterday, without finishing up my comment:

Digging some more, aria-describedby might come to the rescue of the two element solution. Support in 2018 AT/browser combination seems sufficient.

Nonetheless, we should probably also add a for attribute (and test). There's nothing more disappointing than a label not connected to the widget it's meant for.

I think <label id="bar" for="foo">…</label><input id="foo" /> is roughly equivalent to <label id="bar">…</label><input id="foo" aria-labelledby="bar" />, so if we're going to use aria-describedby instead, we should probably not use for?

Edit: yeah, it is roughly equivalent, compare step 2B and 2D in

No, cause with only aria-labelledby or aria-describedby you loose the inert focusability or in the case of checkboxes/radios toggling functionality through the label.

I am not sure if that is desirable for the additional help text to do that when clicked. But I don't really care, it should be harmless. So we can use both, I guess.

The aria-describedby attribute is already added when the help is in the popup, I missed adding it to the inline one when working on rGOJUcaf3fe46457f: FieldLayout: Add 'helpInline' config. The fix for that and some minor refactoring —

To pick up @matmarex comment:
In my conviction if we agree that the contents of the inlined help is describing the (closest) input control, it should be a label element and in order to machine-readable associate the label element with the form control it has to feature a for attribute or enclose the form control.
Although the HTML Standard is ambigious about the association need:

[…]The caption can be associated with a specific form control
[…]The for attribute may be specified to indicate a form control with which the caption is to be associated

there are no given examples of a standalone label element, as it makes semantically no sense.

On the other hand, If we say the inlined comment is anything not related to the input, then a label makes no sense. See also my comment at T197004#4314770

There is some ambiguity around the for attribute:

From MDN:

The id of a labelable form-related element in the same document as the label element. The first such element in the document with an ID matching the value of the for attribute is the labeled control for this label element.

One input can be associated with multiple labels.

From the HTML 4 Spec

More than one LABEL may be associated with the same control by creating multiple references via the for attribute.

So it seems that multiple labels with for attributes are… ok to use? Even though they might not always be 'linked'. Anyway, our other label should be linked by the aria-describedby attribute [1]. I am for adding the for attribute to the help label too [2].


Vvjjkkii renamed this task from Inlined help needs to be part of widget's `<label>` element to debaaaaaaa.Jul 1 2018, 1:05 AM
Vvjjkkii removed Prtksxna as the assignee of this task.
Vvjjkkii updated the task description. (Show Details)
Vvjjkkii edited subscribers, added: Prtksxna; removed: Aklapper.
CommunityTechBot renamed this task from debaaaaaaa to Inlined help needs to be part of widget's `<label>` element .Jul 2 2018, 8:38 AM
CommunityTechBot assigned this task to Prtksxna.
CommunityTechBot updated the task description. (Show Details)
CommunityTechBot edited subscribers, added: Aklapper; removed: Prtksxna.
Prtksxna added a subscriber: Prtksxna.
matmarex claimed this task.

I think Prateek mostly solved the problem with rGOJUaa86508242c4: FieldLayout: Add 'for' attribute to inline help label.

Changing the DOM to put the label and inline help into a single <label> element is impossible now because of rGOJUe46ad7f60832: FieldLayout inline help: Move help after field when align=top (label is before the field, inline help is after it), so I will mark this as declined.