Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behaviour of option elements with hidden attribute #3063

Open
tristanlbailey opened this issue Sep 23, 2017 · 5 comments
Open

Behaviour of option elements with hidden attribute #3063

tristanlbailey opened this issue Sep 23, 2017 · 5 comments
Labels
accessibility Affects accessibility interop Implementations are not interoperable with each other topic: forms

Comments

@tristanlbailey
Copy link

I have uncovered inconsistencies in the behaviour of option elements with the hidden attribute across popular used web browsers (Google Chrome, Firefox, Internet Explorer) . After having posted a bug report on Google Chrome, I am now wondering what the correct behaviour should be.

With Google Chrome, if the first/top-most option in the list has the hidden attribute applied, it is still displayed in the select element. Further, while hidden option elements are not displayed in the select element's item list, they are still accessible when typing matching characters on the keyboard, or using the arrow keys.

Firefox also continues to display the first/top-most option element (hidden), but does not allow hidden option elements to be accessed.

Internet Explorer 11 completely disregards the existence of the hidden attribute on option elements.

The W3C spec states:

"When specified on an element, it indicates that the element is not yet, or is no longer, directly relevant to the page's current state, or that it is being used to declare content to be reused by other parts of the page as opposed to being directly accessed by the user."

I have highlighted what I believe to be the most pertinent part of the statement. Accessibility. Theoretically, given this statement, a user should not be able to access the hidden data. In this context, a user should not be able to type their way to displaying an option element with the hidden attribute.

The spec also states:

"The hidden attribute must not be used to hide content just from one presentation — if something is marked hidden, it is hidden from all presentations, including, for instance, screen readers."

Taking this into account, if an element has the hidden attribute, then shouldn't it be hidden absolutely everywhere on a webpage, or not? Conversely, if something is visible on the screen, then why shouldn't a screen reader be able to read it?

A Google Chrome moderator has asked me to lodge a report, here. The moderator also mentioned the "ask-for-a-reset algorithm", but I am not sure how that applies to the behaviour in discussion.

So, is there an exception to the rule here, or should the meaning of something using the hidden attribute be redefined?

References to global hidden attribute:
W3C - https://www.w3.org/TR/2016/REC-html51-20161101/editing.html#the-hidden-attribute
WHATWG - https://html.spec.whatwg.org/multipage/interaction.html#the-hidden-attribute

@annevk annevk added interop Implementations are not interoperable with each other topic: forms labels Sep 24, 2017
@annevk
Copy link
Member

annevk commented Sep 24, 2017

Thanks for the report!

I suspect this would affect <datalist> as well. Not really sure what is best here. The question is basically whether the "binding" for <select> and <datalist> needs to take this into account or not.

I suspect what you are observing will be identical to when you use display:none on <option> elements.

@tristanlbailey
Copy link
Author

tristanlbailey commented Sep 26, 2017

Now that you have mentioned the datalist element, I could have actually used that in my project to begin with!

Yes, setting the CSS display property to "none" has the exact same effect in all 3 web browsers. In other words, no changes from using the hidden attribute in each browser.

As I am not a professional web developer, I cannot comment on the intricacies of HTML elements with respect to the HTML specifications. I will note, however, that the behaviour of initially keeping the top-most option element visible while it has either hidden attribute or display style set to none, has the advantage that the option disappears after the user has made a selection. This effect is perhaps best used when a web developer wishes to use an option element to ask the user to select an option, when an option is required. The request would then disappear after an option is selected.

In my personal opinion, hidden option elements should not be accessible through keystrokes.

@domenic
Copy link
Member

domenic commented Oct 6, 2017

This is interesting indeed. Here's my analysis.

What does hidden actually require?

The only actual requirements on the user agent that hidden implies are "User agents should not render elements that have the hidden attribute specified.".

The part you quote, about "hidden from all presentations", is not actually a requirement on user agents. It's more relying on the fact that screen readers only display things that are rendered, and using that to give guidance to authors about when the hidden attribute is appropriate. I agree it is kind of unclear, and should be rephrased to say something like "if something is marked as hidden, the user agent will not render it, which will, for instance, stop screen readers from reading it."

So, hidden is really just a shorthand for some CSS. Like CSS display: none, it stops things from being rendered. And that---no more, no less---is what the spec requires.

So, what does "render" mean?

The big question is then why Chrome renders <option> elements that the CSS system says not to render. E.g. https://jsbin.com/hosijimila/edit?html,output shows this without bringing the hidden attribute into the discussion at all.

This is an interop problem, and we should figure out a way to solve it. I'm not sure what the right solution is, though, because...

Disabling form elements

The spec is pretty clear that if you want something to become "inactive" in a form, including an option element, you need to use the disabled attribute. A lot of stuff flows from this, and I don't think we should make hiding something with CSS apply all the same effects as disabling.

This is why @tkent-google was pointing to the ask-for-a-reset algorithm. That's the algorithm which determines which option gets initially selected. And it only omits the disabled options; it doesn't omit ones that are visually hidden.

Conclusion

I see two paths:

  • Treat hidden/CSS display: none as a purely visual thing. This implies forms should choose the hidden options, allow selection of them, typeahead to them, etc. Probably this still means Chrome should change, so that https://jsbin.com/hosijimila/edit?html,output shows an "invisible" selected option instead of showing the text "Default".
  • Invent a new rule that CSS visibility affects select and datalist elements. Basically, this would be saying that both disabled and CSS visibility both affect how the default option is chosen and what list of options is displayed or selectable.

I'm not sure which is best. I guess the former is what the spec supports right now. It would be good to do more testing, e.g., try something like https://jsbin.com/hosijimila/edit?html,output in all browsers and test what optionEl.selectedIndex is. (If it's 0, browsers follow the current spec, and they only differ in what they visually present. If it's -1, browsers are already doing something like the latter option.)

@tristanlbailey
Copy link
Author

Thanks, Dominic.
OK, so using your example in JS Bin, Chrome says '-1' for the selected index, Firefox also '-1', and Internet Explorer 11 is being a typical PITA, so I can't deduce the value there.
Actually, the current spec says the value should be '-1' when nothing is selected, so at least Chrome and Firefox matches that.

@scottaohara
Copy link
Collaborator

Came across this issue today and did some investigation so hopefully this will be helpful:
https://codepen.io/scottohara/pen/MWEjmOg

Quickly, Chromium, Firefox and Webkit all behave differently here.

  1. Webkit (macos & ios) doesn't respect the hidden attribute/CSS on option elements. So, as far as a user is concerned no unexpected behavior.
  2. Firefox will expose a hidden option, if it has the selected attribute the default selection in a collapsed select. Once the user changes the value, the hidden option becomes inaccessible to them (with / without a screen reader).
  3. Chromium browsers, as per this issue/the chromium bug, partially treat the hidden option as if it wasn't there, but also can allow access to it if a user uses character keys to try and change the current selection.

FWIW, I like Firefox's behavior here... it solves the problem I've seen developers face where a design calls for a collapsed select element to have a default cta value - e.g., "choose an option...", but they don't want it to appear in the exposed listbox of options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility Affects accessibility interop Implementations are not interoperable with each other topic: forms
Development

No branches or pull requests

4 participants