-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
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
False value cause aria boolean attributes to be removed from the DOM #11053
Comments
I didn't check out the repro as i don't have access to dropbox. But:
I don't think it makes sense to have aria attributes behave differently than other html attributes in this regard. Also, we need a way to tell Vue "remove that attribute", which is setting it to We're aware that this works a bit differently than vanilla js: el.setAttribute('aria-selected', false)
<div aria-selected="false">
el.setAttribute('checked', false)
<div aria-selected="false" checked="false">
el.setAttribute('placeholder', false)
<div aria-selected="false" checked="false" placeholder="false"> So Vue treats |
For Aria attributes you have to cast them to string: <button :aria-pressed="isToggled.toString()"> This is something I thought about but didn't take the time to make sure that
If those two points are true, I think it would make for aria attributes on HTML elements to be cast as strings |
@LinusBorg thanks for your clarification. I do understand the reason behind this behavior, but I think that having to cast ARIA attributes to string manually is tedious and degrades the developer experience. In addition to this, even if they do appear as html boolean attributes conceptually, according to the W3C specification
Together with the fact that if the value is to true you get a statement like Also, the fact that an ARIA attribute has the false value can mean something different than completely omitting the attribute (think of aria-expanded, just to mention the one I used in the demo). |
@posva thanks for providing a code example, this is the workaround I am using right now. I think that automatically casting ARIA attribute values to strings makes sense. Regarding your first point I think that the answer is yes (see my previous comment), while the answer to your second point is yes unless W3C suggests different type mappings. |
That's kind of my point: if we cast But yeah I can see how casting would be helpful in practice. Will reopen just to discuss it further |
I was just looking at an older, closed issue on the same topic: #7422 (comment). What about just addressing this in the docs? Maybe specifically calling out bindings of |
This behavior was actually changed in Vue 3, unfortunately, and should be immediately reverted. (See https://v3.vuejs.org/guide/migration/attribute-coercion.html#overview) I came here looking to file an issue because upgrading to v3 broke most of my templates due to this change. I saw this issue was still open, so I'm adding my feedback. With Vue 3 it is now a HUGE pain for developers to get boolean attribute bindings working correctly as our code now has to reassign completely legitimate Two use cases to illustrate: I have a permissions UI where the permissions come from a data store with permission values stored as This is resulting in some really weird and ugly code. I've never had to do something like this in my 10+ years writing JavaScript. Non-boolean attributes, in particular those that expect the string For the sake of Vue's ease-of-use and cleanliness, please consider reverting! In the meantime, guaranteed broken boolean attributes is absolutely a big enough problem to warrant highlighting it in the "Breaking Changes" section of the Migration Guide. I caught this after migration during e2e testing and eventually found "Attributes coercion strategy changed" in the "Other minor changes" section. Please call this out in "Breaking Changes". |
This is a breaking change improvement so it won't be possible to add to Vue 2 but it's working properly in Vue 3 by automatically casting |
How it should be:
How we have to dance around this new bizarre behavior:
|
Vue can't know which custom attribute of a web component is meant to be a boolean attribute (as opposed to actual HTML attributes wich are defined as being boolean or not ion the spec). So we treat custom attributes as non-boolean attributes. But: Most Web component implementations sync custom attributes to DOM properties and vice versa (see here). For web components that do this, the described problem doesn't really exist, in my experience: When Vue can find a DOM property named This way, there is no special treatment necessary - the web component will receive a plain boolean value through the DOM property and can decide how to deal with it (remove the attribute, or set it with a stringified value) according to how it defined that property's type. You seem to be using a web component implementation that doesn't do this, which is unfortunate for for this specific case. |
@LinusBorg your explanation/defense of Vue 2 behavior at the top of this issue (#11053 (comment)) was sound and Vue should have stuck with it. It was one of the few frameworks that Just Worked. React is struggling with this exact issue too (facebook/react#9230) and Vue 3 now conflicts with custom attributes just like React! As someone who made the switch that's really frustrating. There doesn't seem to be any open discussion about this breaking change and the reasoning behind it (please share if there was), so what happened? Also, Vue's new behavior is not consistent with JavaScript: Even more, CSS authors have to rewrite attribute selectors to accommodate this change in behavior (same problem in React world facebook/react#9230 (comment)). It really seems like this breaking change should be reconsidered. The old behavior Just Worked. And what's so confusing about all this, is the solution to the original problem was incredibly easy to solve for: The intuitive treatment of |
Just spent an hour refactoring some semi-complicated computed properties. Never knew how much of a pain it is to get JS to evaluate to exactly |
Alright, vue.js GitHub issues are simply not the place to drop your frustration. The improvement went through an RFC in the rfcs repo, which you are free to check. You can also propose a new discussion to change this behavior but to be honest, you are the only person complaining about the improvement of writing |
Version
2.6.11
Reproduction link
https://www.dropbox.com/s/3ltqeent65djedw/problematic-false-aria-values.zip?dl=0
Steps to reproduce
yarn install
).yarn serve
) and head to its url with your favorite browser.aria-checked
andaria-expanded
attributes won't be there.aria-checked
andaria-expanded
will be there as expected.aria-checked
andaria-expanded
attributes won't be there, again.What is expected?
Aria attributes should be present in the DOM even if their value is false.
What is actually happening?
Aria attributes are not present in the DOM when their value is false.
Unlike for html 5 boolean values, removing aria attributes from the DOM when their value is false changes the page semantics and degrades its accessibility, causing markup validation issues as well.
The text was updated successfully, but these errors were encountered: