{"id":966,"date":"2024-01-12T17:05:46","date_gmt":"2024-01-12T17:05:46","guid":{"rendered":"https:\/\/html5accessibility.com\/stuff\/?p=966"},"modified":"2024-02-08T11:53:29","modified_gmt":"2024-02-08T11:53:29","slug":"options-for-optgroup-labeling-of-options","status":"publish","type":"post","link":"https:\/\/html5accessibility.com\/stuff\/2024\/01\/12\/options-for-optgroup-labeling-of-options\/","title":{"rendered":"options for optgroup labeling of options"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-969\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/IMG_8097.jpg\" alt=\"philosoraptor ponders their options: Deque University or Level Access Academy?\" width=\"500\" height=\"500\" srcset=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/IMG_8097.jpg 500w, https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/IMG_8097-300x300.jpg 300w, https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/IMG_8097-150x150.jpg 150w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>An ugly truth is that there are still interoperability issues with some of the native HTML controls and Screen readers. Even though these controls have been around since long before AI came to the rescue of our accessibility <em>asses<\/em>.<\/p>\n<p>A case in point is the expression of <code>option<\/code> group labels, AKA (Also Known As) <code>&lt;optgroup label=\"poot\"&gt;<\/code> What is exposed in the accessibility tree for <code>&lt;select size=\"1\"&gt;<\/code> and <code>size=&gt;1<\/code> still differs in some browsers (i.e. Chrome)<\/p>\n<h2>Chrome size=1<\/h2>\n<p><code>&lt;select&gt;<\/code> exposed as a <code>combobox<\/code>,\u00a0 <code>&lt;optgroup&gt;<\/code> is not exposed, there is a <code>MenuListPopup<\/code>\u00a0containing the 4 <code>menuitem<\/code>&#8216;s<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-973 size-full\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1.png\" alt=\"Snippet from the Accessibility Tree as displayed in the Chrome DevTools Elements Accessibility panel. there is a combobox named 'ingredients 2'. This combobox has several attributes: focusable: true indicates that the combobox can receive keyboard focus. expanded: false suggests that the combobox is currently collapsed. There are four menuitem elements, each representing a selectable option.\" width=\"450\" height=\"147\" srcset=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1.png 450w, https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1-300x98.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<h2>Chrome size=&gt;1<\/h2>\n<p><code>&lt;select&gt;<\/code> exposed as a <code>listbox<\/code>, each <code>&lt;optgroup&gt;<\/code> is a <code>group<\/code> with child options, the <code>&lt;optgroup&gt;<\/code> <code>label<\/code> attribute value is used as the accessible name for the group.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-972 size-full\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size6.png\" alt=\"screenshot of select size=6 as represented in the accessibility tree in Chrome. ChatGPT says: a listbox widget named &quot;ingredients 1&quot;. This listbox is described by several properties: it is focusable (meaning it can be navigated to using a keyboard or other input methods), not multi-selectable (only one option can be selected at a time), and not required (meaning a selection does not have to be made for form completion). Within the listbox, there are two groups. The first group is labeled &quot;vegetables&quot; and contains two options: &quot;tomato&quot; and &quot;carrot&quot;. The &quot;tomato&quot; option is focusable but not selected, while the &quot;carrot&quot; option is focusable and is currently selected. The second group within the listbox is labeled &quot;fruits&quot; and also contains two options: &quot;apple&quot; and &quot;pear&quot;. Both of these options are focusable but neither is selected. This structured representation indicates a listbox that is organized into categories, allowing users to select one ingredient from a categorized list. The selection state is clearly indicated, showing that 'carrot' is the currently selected option.\" width=\"631\" height=\"183\" srcset=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size6.png 631w, https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size6-300x87.png 300w\" sizes=\"auto, (max-width: 631px) 100vw, 631px\" \/><\/p>\n<h2>Firefox size=1<\/h2>\n<p>The representation for the <code>select<\/code> does expose the <code>optgroup<\/code> element&#8217;s as <code>group<\/code>&#8216;s in the accessibility tree, <em>unlike<\/em> Chrome.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-974 size-full\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size6-firefox.png\" alt=\"a combobox with the name 'ingredients 2' which contains a listbox. Inside the listbox, there is a group labeled 'vegetables' with options 'tomato' and 'carrot', and another group labeled 'fruits' with options 'apple' and 'pear'.\" width=\"503\" height=\"169\" srcset=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size6-firefox.png 503w, https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size6-firefox-300x101.png 300w\" sizes=\"auto, (max-width: 503px) 100vw, 503px\" \/><\/p>\n<h2>Firefox size=&gt;1<\/h2>\n<p><code>&lt;select&gt;<\/code> exposed as a <code>listbox<\/code>, each <code>&lt;optgroup&gt;<\/code> is a <code>group<\/code> with child options, the <code>&lt;optgroup&gt;<\/code> <code>label<\/code> attribute value is used as the accessible name for the group.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-975 size-full\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1-firefox.png\" alt=\"The main container is a listbox with the name 'ingredients 1'. Within this listbox, there are two groups: The first group is labeled 'vegetables'. It contains: A static text element with the text 'vegetables'. Two options: 'tomato' and 'carrot'. The second group is labeled 'fruits'. It contains: A static text element with the text 'fruits'. Two options: 'apple' and 'pear'.\" width=\"519\" height=\"238\" srcset=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1-firefox.png 519w, https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1-firefox-300x138.png 300w\" sizes=\"auto, (max-width: 519px) 100vw, 519px\" \/><\/p>\n<h2>Frigging about<\/h2>\n<p>I <em>frigged about<\/em> with the code, what I wanted was to have JAWS and NVDA to announce the <code>group<\/code> labels along with the <code>option<\/code> labels, regardless of the browser and <code>select size<\/code> and state, in the case of <code>size=\"1\"<\/code> (on desktop browsers) the <code>select<\/code> can be operated (using the keyboard) in the collapsed or expanded state. In fact JAWS advises the user to interact with the control in the collapsed state (which is helpful as I would later realise). When a closed <code>select<\/code> receives focus it announces &#8220;combobox, to change the selection use the arrow keys&#8221;.<\/p>\n<p class=\"note\">When in the collapsed state, neither JAWS or NVDA announce the group labels. For some reason when in the expanded state in Firefox, JAWS <strong>does not<\/strong> announce the group labels, but it does recognize that the option&#8217;s are divided into groups&#8230;. NVDA <strong>does<\/strong> announce as expected.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-978 size-full\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1-collapsed.png\" alt=\"Collapsed select (combobox) with only the selected option 'pear' displayed.\" width=\"105\" height=\"42\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-979 size-full\" src=\"https:\/\/html5accessibility.com\/stuff\/wp-content\/uploads\/2024\/01\/select-size1-expanded.png\" alt=\"a dropdown menu with various options grouped under two categories. The categories labels are in bold black text, indicating they are non-selectable headers. The first category is 'vegetables', under which the options 'tomato' and 'carrot' are listed. The second category is 'fruits', with 'apple' and 'pear' as the selectable options. 'Pear' is selected in the dropdown, as indicated by it being highlighted in blue. The dropdown menu is currently expanded, showing all the available options.\" width=\"108\" height=\"164\" \/><\/p>\n<p>Unfortunately even in the case where the group labels <em>are exposed<\/em>\u00a0in the Chrome accessibility tree (in the <code>size=&gt;1<\/code> case), they are not announced by JAWS or NVDA. I suspect this is due to some property not displayed in the Chrome dev tools accessibility tree, which is causing them to be ignored as they are announced in Firefox, (by NVDA) when the popup is displayed. This is <a href=\"https:\/\/bugs.chromium.org\/p\/chromium\/issues\/detail?id=817579#c11\">acknowledged by Google acc engineers<\/a> as a gap in Chrome&#8217;s support.<\/p>\n<h2>The outcome of the code frigging<\/h2>\n<p>I found that I needed to add <a href=\"https:\/\/html5accessibility.com\/stuff\/2020\/11\/07\/not-so-short-note-on-aria-label-usage-big-table-edition\/\"><code>aria-label<\/code><\/a> to each <code>option<\/code> which included both the <code>optgroup label<\/code> and the <code>option label<\/code>, by doing so the information was announced consistently by NVDA and JAWS\u00a0 in Chrome and Firefox.<\/p>\n<p>Of course this is <em>not ideal<\/em> as it requires the addition of ARIA and the duplication of the group label. But the exercise was not about theoretical purity of things working as they should, but about how to convey the information to screen reader users as it is to others.<\/p>\n<p>Using the <code>aria-label<\/code> on the <code>option<\/code> element with both the <code>optgroup<\/code> and <code>option<\/code> labels as content, provides robust support across browsers and screen readers:<\/p>\n<pre>&lt;optgroup label=\"fruits\"&gt;\r\n&lt;option <mark>aria-label=\"fruits apple\"<\/mark>&gt;apple\r\n&lt;option <mark>aria-label=\"fruits pear\"<\/mark>&gt;pear\r\n&lt;\/optgroup&gt;<\/pre>\n<h3>Too much effort?<\/h3>\n<p>It <em>should be<\/em> relatively simple to implement via post rendering scripting if necessary, the automated addition of the <code>aria-label<\/code>&#8216;s using the labels already present in the DOM.<\/p>\n<p>I asked ChatGPT to create a script to do just that, as a proof of concept. It provided me with the following:<\/p>\n<pre>javascript:(function() {\r\ndocument.querySelectorAll('select').forEach(select =&gt; {\r\nselect.querySelectorAll('optgroup').forEach(optgroup =&gt; {\r\nconst groupLabel = optgroup.getAttribute('label');\r\nif (groupLabel) {\r\noptgroup.querySelectorAll('option').forEach(option =&gt; {\r\nconst optionLabel = option.getAttribute('label') || option.textContent;\r\noption.setAttribute('aria-label', `${groupLabel}: ${optionLabel}`);\r\n});\r\n}\r\n});\r\n});\r\n})();<\/pre>\n<h3>try it on for size<\/h3>\n<p class=\"codepen\" style=\"height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;\" data-height=\"300\" data-default-tab=\"result\" data-slug-hash=\"zYbqZRX\" data-user=\"stevef\">See the Pen <a href=\"https:\/\/codepen.io\/stevef\/pen\/zYbqZRX\"><br \/>\nUsing JavaScript to polyfill group labelling support<\/a> by steve faulkner (<a href=\"https:\/\/codepen.io\/stevef\">@stevef<\/a>)<br \/>\non <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/p>\n<p><script async src=\"https:\/\/cpwebassets.codepen.io\/assets\/embed\/ei.js\"><\/script><\/p>\n<h2>Further reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/html5accessibility.com\/stuff\/2020\/11\/07\/not-so-short-note-on-aria-label-usage-big-table-edition\/\">Not so short note on aria-label usage \u2013 Big Table Edition<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/FreedomScientific\/standards-support\/issues\/243\">optgroup is not output for drop-down lists (Firefox)<\/a><\/li>\n<li><a href=\"https:\/\/codepen.io\/stevef\/pen\/zYbqZRX\">Using JavaScript to polyfill group labelling support (codepen)<\/a><\/li>\n<li><a href=\"https:\/\/codepen.io\/stevef\/pen\/OJqNpEg\">option with aria-label=&#8221;group label, option label&#8221;<\/a><\/li>\n<\/ul>\n<h2>Further listening<\/h2>\n<p><iframe loading=\"lazy\" title=\"YouTube video player\" src=\"https:\/\/www.youtube.com\/embed\/scMFJcHc7MA?si=LylxzjUYtBapgimo\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen=\"allowfullscreen\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>An ugly truth is that there are still interoperability issues with some of the native HTML controls and Screen readers. Even though these controls have been around since long before AI came to the rescue of our accessibility asses. A case in point is the expression of option group labels, AKA (Also Known As) &lt;optgroup [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-966","post","type-post","status-publish","format-standard","hentry","category-htmlaccessibility"],"_links":{"self":[{"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/posts\/966","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/comments?post=966"}],"version-history":[{"count":22,"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/posts\/966\/revisions"}],"predecessor-version":[{"id":1015,"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/posts\/966\/revisions\/1015"}],"wp:attachment":[{"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/media?parent=966"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/categories?post=966"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/html5accessibility.com\/stuff\/wp-json\/wp\/v2\/tags?post=966"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}