Home > Net >  Colons after labels; any accessibility concerns?
Colons after labels; any accessibility concerns?

Time:04-09

I like having a colon after labels but for form-building components I like not having to specify them. Thus I have CSS like this:

label::after {
  content: ':';
}

This works fine, but my puppeteer scripts, which use aria selectors, are not finding inputs that are labeled like that due to the colon showing up in the accessible names. For example, given this:

<label for="first-name">First name</label><input id="first-name" type="text" />

The selector aria/First name fails to find the input.

I can add a : to the aria selector, but that's annoying, and I'm not sure if the colon ends up as noise to those using screen readers and this is misplaced worry or if there's a cleaner way to do this where the colon shows up for sighted readers but is invisible to screen readers.

CodePudding user response:

Using the alt feature of CSS:content is creative but mainly works on Chrome (and Edge, since it's chromium). Firefox and Safari don't support it (yet) and in fact it makes the content property invalid on those browsers so your content is not displayed at all.

On Chrome, it's not exactly fully supported either. The alt text is honored for url content:

label::after {
  content: url(image.gif) / "my alt text";
}

meaning that when you navigate with a screen reader to the label, or the input associated with that label, you'll hear the alt text.

But for text content, the alt text is not used. It treats all alt text as NULL.

label::after {
  content: "hello" / "my alt text"; 
}
label::after {
  content: "hello" / ""; 
}

Both of these examples cause the content to not be used in the accessible name calculation (Step 2.F.ii in https://www.w3.org/TR/accname-1.1/#step2), which gives you what you want for puppeteer - an ARIA selector that doesn't have the content.

An alternative way to do this that is supported on all browsers is to have your content on an element with aria-hidden="true".

<style>
.foo::after {
  content: ':';
}
<style>

<label for="first-name">First name<span  aria-hidden="true"></span></label>
<input id="first-name" type="text" />

CodePudding user response:

I found a workaround while typing the question. Apparently alt text for content can be specified, so this works to show a ":" but render it invisible to the accessibility tree. The content property is repeated to catch browsers that don't support this syntax. This seems to be setting the accessible name of labeled inputs to not include the :.

label::after {
  content: ':';
  content: ':' / '';
}
  • Related