Splitting within Selects
The native HTML <select>
is renowned for its styling limitations. Even with control over the closed state and trigger appearance, the options themselves are still defined primarily by the browser and the OS. While I think this is generally fine (preferred, even), the <selectlist>
(nee <selectmenu>
) hopes to change that.
But until that happens, Apple and Google feel it is important to:
…add
<hr>
(horizontal rule) elements into the list of select options and they will appear as separators to help visually break up the options for a better user experience.
This feature is not the same as <optgroup>
. Whether or not that matters for you depends on your use case and needed support.
Since some may consider me a bit of an accessibility curmudgeon, I am going to try to limit my own opinions in this post and report current behavior.
Demo
I made a demo to compare these two methods for splitting options.
The first is from the Google Chrome’s Select element: now with horizontal rules. This case is for when you want to offer a visual cue to group options together, but don’t feel you need to convey those groups to all users.
The second is from MDN’s <optgroup>
: The Option Group element. This case is when you want to both group options and name the groups, both visually and programmatically.
You can also visit the demo directly.
Key for the icons used in the lists that follow:
- Good, meaning it works well for everyone;
- Fine, but could be improved;
- Caution, has issues but may be ok in some cases;
- Buggy, probably avoid.
Using <hr>
My sample code:
<select name="majors" id="major-select">
<option value="">Select a major</option>
<hr>
<option value="arth">Art History</option>
<option value="finearts">Fine Arts</option>
<option value="gdes">Graphic Design</option>
<option value="lit">Literature</option>
<option value="music">Music</option>
<hr>
<option value="aeroeng">Aerospace Engineering</option>
<option value="biochemeng">Biochemical Engineering</option>
<option value="civileng">Civil Engineering</option>
<option value="compeng">Computer Engineering</option>
<option value="eleng">Electrical Engineering</option>
<option value="mecheng">Mechanical Engineering</option>
<hr>
<option value="polysci">Political Science</option>
<option value="intr">International Relations</option>
<option value="bizdev">Business Development</option>
<hr>
<option value="math">Mathematics</option>
<option value="econ">Economics</option>
<option value="stat">Statistics</option>
</select>
The tests are a bit unfair since I am using current and older versions of Firefox, a beta release of Chrome, and the latest Safari.
Desktop
Firefox 118 / Windows 11:
- does not expose the
<hr>
visually in the page; - does not expose the
<hr>
programmatically in the rendered DOM; - does not expose the
<hr>
within the accessibility tree; - does not announce the
<hr>
when using NVDA; - has no contrast concern since it does not appear.
Firefox 115 / Ubuntu 22.04.2 LTS:
- does not expose the
<hr>
visually in the page; - does not expose the
<hr>
programmatically in the rendered DOM; - does not expose the
<hr>
within the accessibility tree; - does not announce the
<hr>
when using NVDA; - has no contrast concern since it does not appear.
Chrome Canary (120) / Windows 11:
- exposes the
<hr>
visually in the page only when the menu is expanded (arrowing within the collapsed menu does not show them); - exposes the
<hr>
programmatically in the rendered DOM; - does not expose the
<hr>
within the accessibility tree; - does not announce the
<hr>
when using JAWS; - has sufficient contrast since it matches the text color.
Safari 17 / macOS 14.0:
- exposes the
<hr>
visually in the page (arrowing within the collapsed menu expands it); - exposes the
<hr>
programmatically in the rendered DOM; - does not expose the
<hr>
within the accessibility tree; - does not announce the
<hr>
when using VoiceOver; - has insufficient contrast (1.3:1), though the spacing arguably does the job.
Mobile
Firefox 118 / Android 13:
- does not expose the
<hr>
visually in the page; - does not announce the
<hr>
when using TalkBack; - has no contrast concern since it does not appear.
Chrome Canary (120) / Android 13:
- exposes the
<hr>
as its own empty selectable option; - does not announce the
<hr>
when using TalkBack, but is a swipe-stop; - has unknown contrast since it is blank.
Safari 17 / iPadOS 17.0.3:
- does not expose the
<hr>
visually in the page; - does not announce the
<hr>
when using VoiceOver, because it is not in the page; - has unknown contrast since it is blank.
Using <optgroup>
My sample code:
<select id="dino-select">
<optgroup label="Theropods">
<option>Tyrannosaurus</option>
<option>Velociraptor</option>
<option>Deinonychus</option>
</optgroup>
<optgroup label="Sauropods">
<option>Diplodocus</option>
<option>Saltasaurus</option>
<option>Apatosaurus</option>
</optgroup>
</select>
The tests are a bit unfair since I am using current and older versions of Firefox, a beta release of Chrome, and the latest Safari.
Desktop
Firefox 118 / Windows 11:
- exposes the
<optgroup>
visually in the page only when the menu is expanded (arrowing within the collapsed menu does not show them); - exposes the
<optgroup>
programmatically in the rendered DOM; - exposes the
<optgroup>
within the accessibility tree; - announces the
<optgroup>
when using NVDA if I expand the control; - has sufficient contrast since it matches the text color.
Firefox 115 / Ubuntu 22.04.2 LTS:
- exposes the
<optgroup>
visually in the page only when the menu is expanded (arrowing within the collapsed menu does not show them); - exposes the
<optgroup>
programmatically in the rendered DOM; - exposes the
<optgroup>
within the accessibility tree; - does not announce the
<optgroup>
when using Orca if I expand the control; - has sufficient contrast since it matches the text color.
Chrome Canary (120) / Windows 11:
- exposes the
<optgroup>
visually in the page only when the menu is expanded (arrowing within the collapsed menu does not show them); - exposes the
<optgroup>
programmatically in the rendered DOM; - does not expose the
<optgroup>
within the accessibility tree; - does not announce the
<optgroup>
when using JAWS; - has sufficient contrast since it matches the text color.
Safari 17 / macOS 14.0:
- exposes the
<optgroup>
visually in the page (arrowing within the collapsed menu expands it); - exposes the
<optgroup>
programmatically in the rendered DOM; - does not expose the
<optgroup>
within the accessibility tree; - announces the
<optgroup>
as “dimmed” when using VoiceOver; - has insufficient contrast (1.4:1), making the text essentially useless to low vision users.
Mobile
Firefox 118 / Android 13:
- exposes the
<optgroup>
visually in the page; - announces the
<optgroup>
as “disabled” when using TalkBack; - has insufficient text contrast (2.9:1).
Chrome Canary (120) / Android 13:
- exposes the
<optgroup>
visually in the page; - announces the
<optgroup>
when using TalkBack, but is an unselectable swipe-stop; - has sufficient contrast since it matches the text color.
Safari 17 / iPadOS 17.0.3:
- exposes the
<optgroup>
visually in the page; - announces the
<optgroup>
when using VoiceOver, but is an unselectable swipe-stop; - has insufficient text contrast.
History
Because it is interesting to see how standards and browsers move, sometimes in lockstep and sometimes not, I did a little digging. This is also a good indicator of priorities.
<hr>
in <select>
Way back in 2005, Safari 2.0.2 added support for <hr>
in <select>
, even though it was not to spec. It was so popular that nobody remembered. It also did not work without JavaScript, as Kent Tamura noted in 2012 with Bug 80686 – HTML parser: allow <hr>
to be used inside <select>
as a separator where it languished for eleven years.
Pulled from the WebKit blog as noted in my 27 January update: Originally it was added by Adele Peterson at Apple in 2006 to support a common UI paradigm on the web: separators between select box options.
It’s not clear why the 2005 date I found is not mentioned in that post.
On 26 January 2018, Eric Shepherd filed #1156: Proposal: Allow adding separator rows to <select> boxes using <hr> against the W3C HTML specification. It was closed six months later after a decision that it was a layout issue and outside the domain of HTML.
On the same day, Eric Shepherd also filed the same issue against the WHATWG HTML specification as #3410: Proposal: Allow adding separator rows to <select> boxes using <hr>. In April 2021 Sam Sneddon discovered the code was in WebKit (and Blink) dating back to 2005.
On 5 April 2023, Anne van Kesteren (Apple) opened WebKit pull request #12407 HTML parser: allow <hr>
to be used inside <select>
as a separator, updating that 2012 bug report at the same time. On the same day, Anne van Kesteren (Apple) opened #9124 Allow <hr> to be used inside <select> as a separator against WHATWG HTML. 27 days later on 2 May 2023 Anne van Kesteren (Apple) merged it (see the current WHATWG HTML entry for the <select>
element). Mason Freed noted there is no Web Platform Test for it.
Also on 2 May 2023, Anne van Kesteren opened #480 Document <hr>-in-<select> against the W3C HTML Accessibility API Mappings (HTML-AAM) spec. Scott O’Hara merged PR #504 Update: hr within select element on 9 October 2023. Read that thread for a little sausage-making insight.
Also also on 2 May 2023, Anne van Kesteren filed issue #26536 Document <hr>-in-<select> to add the just-merged WHATWG HTML change to the MDN HTML documentation. That issue is still open.
Also also also on 2 May 2023, Anne van Kesteren filed #1830909 Implement <hr>-in-<select> against Firefox. That issue is still open.
WebKit Features in Safari 17.0 was posted on 18 September 2023, where it announced this new feature of both the browser and HTML. Without noting support issues (decisions) in VoiceOver.
On 19 September 2023, Joey Arhar (Google) announced Intent to Ship: Horizontal rules inside select elements for Blink (Chrome). The specification reference was the WHATWG HTML Pull Request (not the spec itself). The justification was that Blink’s inherited WebKit had this (broken) code already and that Safari 17 had just announced it as a new feature. The interopability and compatibility notes pointed to Safari, but noted no signal from Mozilla and no signal from web developers.
On 20 September 2023, Joey Arhar opened #887 Allow <hr> tags inside <select> tags against the Mozilla Standards Position repo. It was closed on 2 October 2023 as “positive” (meaning Mozilla is on board). I can find no implementation timeline, but thanks to a pointer from Jamie Teh, we can see it is in progress as of 24 September 2023.
Jamie Teh also gave some insight into option counts in Firefox related to grouping via separators.
To recap:
- 2005: Safari 2.0.2 adds support for
<hr>
in<select>
, which is not allowed by HTML. - 2018: W3C HTML feature request added to allow this, W3C closes as outside scope of HTML.
- 2018: WHAWTG HTML feature request added to allow this, no action taken.
- 5 April 2023: Apple opens WebKit PR to allow
<hr>
in<select>
. - 5 April 2023: Apple opens WHATWG HTML PR to allow
<hr>
in<select>
. - 2 May 2023: Apple rep merges WHATWG HTML PR (sans Web Platform Test).
- 2 May 2023: Apple files issue against HTML-AAM.
- 2 May 2023: Apple files issue to add
<hr>
in<select>
to MDN documenation. - 2 May 2023: Apple files issue to add
<hr>
in<select>
to Firefox. - 18 September 2023: Apple announced Safari 17 supports
<hr>
in<select>
. - 19 September 2023: Google announces intent to ship
<hr>
in<select>
. - 20 September 2023: Google filed issue against Mozilla Standards Position repo.
- 24 September 2023: Mozilla starts work.
<optgroup>
I have a lot less history here.
The <optgroup>
element was in HTML 4.01, which became a W3C Recommendation on 24 December 1999.
A very quick search in the WebKit bug tracker resulted in Bug 175817: OPTGROUP label is not readable on every OPTION from 22 August 2017 which addresses its lack of exposure by VoiceOver.
The same very quick search in the Chromium bug tracker resulted in four accessibility bugs:
- Issue 755269: Optgroup accessibility, 14 August 2017.
- Issue 817579: HTML optgroup elements and their labels not represented in the accessibility tree, 28 February 2018.
- Issue 1130271: optgroup is incorrectly transmitted to the Accessbility API, 19 September 2020.
- Issue 1262384: <select> with <optgroup> should be announced to screenreader, 21 October 2021.
MDN’s browser compatibility chart for <optgroup>
shows full compatibility seemingly since the dawn of browsers. A11ySupport.io, on the other hand, lists <optgroup>
screen reader support as 7 out of 33 using tests from four years to a month ago.
Interestingly, WCAG Technique H85: Using optgroup to group option elements inside a select implies that <optgroup>
is accessibility supported when it is not (despite MDN’s implication).
Verdict
Today only Safari 17 on macOS partially supports <hr>
in <select>
, but that will change when Chrome 119 comes out and also partially supports it. Until Firefox adds support, I would avoid <hr>
in <select>
. When Firefox adds support, I will likely still avoid <hr>
in <select>
until the bugs are ironed out. At the very least, it is a visual-only affordance, so I am not sure it is an equivalent experience for low- and no-vision users.
Instead, consider pushing for bug fixes on <optgroup>
since it provides a visual cue and group label when done well. In my opinion, that is more valuable than a visual-only cue.
Update: 27 October 2023
Playing catch-up.
I Heard You Like Thing in Your Thing so I Put Thing in Your Thing
On the Masto, Matt Machell asked about stuffing an <hr>
into an <optgroup>
. It closes the <optgroup>
(well, browsers will once they all can react to this recent addition):
An
optgroup
element’s end tag can be omitted if theoptgroup
element is immediately followed by anotheroptgroup
element, if it is immediately followed by anhr
element, or if there is no more content in the parent element.
I embedded an example in my demo so you can see how it works today. A rare case where I consider it ugly and weird enough to suggest you avoid it for that reason alone.
Meanwhile…
James Teh (Mozilla, formerly NVDA) weighed in on the closed W3C HTML-AAM PR to note that NVDA users can do a little review cursor navigation to find the separators, while VoiceOver seems to disallow that. He also notes that Firefox calculates position within groups (such as menus and lists) by accounting for separators, well before the spec said not to do that, so this can throw a wrench into current interface expectations. James Craig (Apple) responded and the conversation continues.
Since WHATWG HTML is versionless, and since it essentially only takes one browser implementation to get into WHATWG HTML, and since the people approving PRs to WHATWG HTML seem to be the same ones adding features to Safari and Chrome, perhaps the best way to stay on top of HTML today is to look at Chrome “intent to ship” announcements and Safari feature releases.
Remember that there are long-standing accessibility bugs in all major browsers. Remember that Apple is working hard to erase its huge deficit in baseline support, and pushing changes to HTML and then rushing them to market makes for good PR. Remember that WHATWG’s process generally dismisses accessibility experts and demonstrable problems — it took 872 days to fix <main>
in WHATWG HTML, 2,495 days to fix WHATWG HTML’s wrong advice about the Document Outline Algorithm, but only 27 days for Apple to push this into WHATWG HTML. Remember this as you work on and use the web platform.
Meanwhile, this discussion prompted Wilco Fiers (Deque, axe) to poke his open ARIA issue Why is separator allowed between menuitem, but no other “item” roles?
Update: 14 January 2024
Steve Faulkner wrote options for optgroup labeling of options, where he confirms <optgroup>
is still broken in Chrome. He goes beyond my tests and shows in Chrome that it behave differently between a standard select menu and one with size
greather than 1.
Steve also provides a brute-force ARIA method on group labels within those broken controls, though it is a more verbose experience for non-Chrome users.
In mid-December I opened an issue against MDN for its incorrect browser support charts: #21663 html.elements.optgroup – Incorrect <optgroup>
support. Sadly, when someone notices I expect it will be closed since my more recent issue against <mark>
was closed almost immediately because accessibility support is out of scope for MDN support charts.
Update: 27 January 2024
Apple has shared Bringing Back Horizontal Rules in Select Elements over on the WebKit blog.
It includes a 2006 date I did not have in my timeline above, but which I added.
I really appreciate that Apple also offers these caveats (which I document above):
It’s important to be aware that this feature adds visual separators. They are not announced by assistive technologies like VoiceOver.
It’s also worth noting that the HTML parser only supports
<hr>
as a child of<select>
elements, not as a child of<optgroup>
elements.Lastly, when using a
<select>
element with asize
attribute value greater than 1, the separators are instead rendered as blank space, similar to the space added for<optgroup>
elements.
Anyway, it’s nice to have this added context and insight. I may not be a fan of Apple linking to Twitter as an example of where people are talking about it, but here we are.
5 Comments
Hey Adrian,
For what it’s worth Edge 116 on Windows 10 has the same result as Firefox in your article for
<hr>
:– does not expose the visually in the page;
– does not expose the programmatically in the rendered DOM;
– does not expose the within the accessibility tree;
– does not announce the when using NVDA;
– has no contrast concern since it does not appear.
In response to .I expect Edge 116 will not support
<hr>
in<select>
since even the current release of Chrome does not, and that won’t come until Chrome 119 is released. That means Edge 119 is the earliest I would expect support owing to the common rendering engine.
You should proudly put Accessibility Curmudgeon on your business cards.
I think the is a nice addition (?). But isn’t the ability to fully customize the UI of the option select what developers and designers really want?
In response to .Sure? Probably for many stakeholders too, but certainly not all. Especially for those who cannot thread the needle between an accessible control and a completely custom solution.
Leave a Comment or Response