<a role="button" onClick={someWeirdlyNamedClickHandler}>
Flow content model
</a>
<a> in this case is interactive and is acting as button, since <button> allows only phrasing content inside itself and <a> has a transparent content model, it is not possible to use button is place of link with click handler to make a conforming html
Button elements allow any HTML inside them (more than a tags, iirc).
Can you explain (ideally with examples) what would break if you used a <button type="button">?
@ljharb, nope, what you recalling is incorrect. Take a look at the content models of the <a> and <button> as it is defined in spec.
https://www.w3.org/TR/2014/REC-html5-20141028/text-level-semantics.html#the-a-element
https://www.w3.org/TR/2014/REC-html5-20141028/forms.html#the-button-element
I see the difference between the word "flow" and "transparent" but I'm not sure how that makes a meaningful difference. Can you provide examples?
Worth noting this:
<a role="button" onClick={someWeirdlyNamedClickHandler}>
Flow content model
</a>
wouldn't be focusable so it would be hardly "interactive" for keyboard users.
However, this should pass :) Maybe warning users that a button is preferred.
<a href="#" role="button" onClick={someWeirdlyNamedClickHandler}>
Link text
</a>
Sorry for the late reply,
@ljharb basically, according to HTML spec you can not put something like div or section, etc in the button tag, of course this will work but result will be an invalid html spec-wise. On the other side, we can use a tag, which has transparent content model, meaning that you can use anything inside a that is permtted by a's parent, except interactive content model.
@afercia you bring an interesting point that I haven't considered. tabindex can be used to hint user-agent that this a should focusable by keyboard.
@dantix yep I know. Strictly speaking, href="#" is just an incomplete fragment identifier ;) it's not a valid value even if validators will pass it. Using tabindex="0" would be slightly better but at that point I'm not sure why one would want to make something like this:
<a role="button" tabindex="0" onClick={someWeirdlyNamedClickHandler}>
and not use a button instead.
@dantix an a tag without a valid href is not focusable as it is not seen as a valid link.
Therefore
<a role="button" tabindex="0" onClick={someWeirdlyNamedClickHandler}>
could also have been a div. The a tag has no meaning anymore.
Not only that, but a button element should also be activated by enter and spacebar, therefore it would also need a keyboard handler to fully act as a button.
The idea here contravenes the first rule of ARIA https://www.w3.org/TR/aria-in-html/#rule1
Whereas it is totally possible to create a button like this, an accessibility checker should reflect the first rule of ARIA instead. In other words, just use a button :)
"Just using a button" is not a perfect alternative to using a link (or a styled span), because you can't apply display: inline to a <button>, it will remain rendered as inline-block (see http://stackoverflow.com/a/27658723, https://www.w3.org/TR/html5/rendering.html#the-button-element-0). In some cases this will not be good enough.
Here's a live demo of the problem: https://jsbin.com/jewaporihe/edit?html,output. What would be your suggestion in this case @AlmeroSteyn?
@n1313 'perfection' can be judged from various angles. If looking at the elements from a semantic perspective and how they are defined and supposed to function and be used, using buttons as buttons and anchors as anchors would be considered the perfect solution. Deviating from the intention of the elements will invariably lead to functional issues.
I cannot offer a solution to your problem as I would really not do it this way. Seriously long control element texts are confusing to sighted and non sighted users alike. Therefore I prefer, when I do something like this, to keep it short and simple describing only the action being performed, or not no intermingle actions with paragraphs of text.
I would always recommend rather adjusting the layout to better make use of the intention of the HTML than to paint myself into a corner which forces me to abandon HTML semantics. Not doing this could lead to a website that I find visually pretty myself, but in doing so I'd be making it hard to impossible for actual people out there to use it.
Just to support @AlmeroSteyn here, Mozilla docs have an explicit warning about this:
Warning: Be careful when marking up links with the button role. Buttons are expected to be triggered using the Space or Enter key, while links are expected to be triggered using the Enter key. In other words, when links are used to behave like buttons, adding role="button" alone is not sufficient. It will also be necessary to add a key event handler that listens for the Space key in order to be consistent with native buttons.
@afercia you bring an interesting point that I haven't considered. tabindex can be used to hint user-agent that this a should focusable by keyboard.
Therefore
<a role="button" tabindex="0" onClick={someWeirdlyNamedClickHandler}>
could also have been a div. The a tag has no meaning anymore.
Deviating from the intention of the elements will invariably lead to functional issues.
Great points all around. @dantix, thank you for opening the issue. I'm going to lay out my thoughts; perhaps there's room for improvement. Most of all I want these lint rules to be useful without prescribing a narrow methodology.
It's true that <a role="button"> and <div role="button"> have the same representation in the AX model. "Semantic" HTML like <a href> and <button> satisfy a contract with the AX model; they provide behavior and the AX model represents them to the user as controls that will exhibit that behavior. ARIA only satisfies the semantic representation part of the contract; it leaves the behavior bit to the developer.
But developers are going to write <a onClick>. And given that reality, I think the best we can do is nudge them to add the code that satisfies the behavior contract. In the master branch you'll find:
no-static-element-interactions -> nudges them to add an interactive role
interactive-supports-focus -> nudges them to add tabindex
click-events-have-key-events -> nudges them to add keypress support.
I've been updating the documentation for these rules with cases. Check out this one.
The end goal is to build accessible UIs. We can use semantic HTML to do that, or build those semantic components from scratch as long as satisfy the contract of semantic role and behavior. In cases where HTML does not give us a HTML element tailored to a specific component (like a combobox, for example) we end up needing to build our own anyway.
What do you think? Can we get to the endpoint you have in mind through the application of the combo of rules that I mentioned?
@jessebeach thanks for sharing your thoughts on the matter.
Firstly let me say I am already happy that you are building and maintaining this tool. It is really great.
I do agree that a more accessible outcome is really the true win and that a11y eutopia rarely exists. So if this leads to more people being able to use websites despite what could be viewed as "bad" HTML, goal achieved.
That said I do want to want to add the following to the <a type="button" discussion. When it comes to non semantic elements, such as div I would always propose using a native element instead of going for ARIA in the first place, but hey, if someone makes an accessible website with ARIA, then okay.
But the anchor is such a base functional element of the web. And users and developers alike generally know and expects what it does, that is, to navigate.
The solution above will no doubt make something that acts like a button, also to AT, given that the developer added tabindex="0" to it, added role="button" and also knew to add a keyboard handler that reacts to both enter and spacebar.
The tabindex is added to make it focusable again, after it was a focusable element in the first place but 'broken' by not adding a valid 'href'. So three 'hints' required just to get the same functionality a 'button' would give. So my question is, would a hint to the developer to use a 'button' instead not be a viable alernative? One vs three :-)
Then say later, or during the maintenance phase of the code, someone else sees there is a handy anchor tag and adds a valid href. What then? Should the linter then warn them to remove the href because it is really actually a button even though it is an anchor tag in the HTML? Because such a hybrid could very easily end up being unusable by a screen reader user. You'd have a button that completely changes context on click without warning.
I would think that as the rules can be turned off and on, this would already give enough flexibility for it not to be blocking and a developer that is hinted to use a button can ignore it just like another one being hinted to now add more ARIA and handlers to the anchor can.
But as I said these are just my thoughts and it is up to you guys to best guard the vision of what you want this awesome tool to be. It certainly is not one or the other, as both would lead to accessible solutions, but the anchor / button decision does lead to a lot of a11y problems out there.
@AlmeroSteyn Thank you for these thoughts!
I would think that as the rules can be turned off and on, this would already give enough flexibility for it not to be blocking and a developer that is hinted to use a button can ignore it just like another one being hinted to now add more ARIA and handlers to the anchor can.
You should put together a PR for this rule.
@jessebeach Great idea!
Done in #219 as a base to discuss.
@jessebeach As I managed to break PR #219 and it got merged instead in #224 this issue was not closed.
Closed in #224
@AlmeroSteyn
The tabindex is added to make it focusable again, after it was a focusable element in the first place but 'broken' by not adding a valid 'href'. So three 'hints' required just to get the same functionality a 'button' would give. So my question is, would a hint to the developer to use a 'button' instead not be a viable alernative? One vs three :-)
Over the years I've shifted from dogma to pragma on this issue. I'm foremost concerned with the user experience and less so with the code the produces it. As long as the experience is satisfactory, I'm willing to forgo strong opinions on how the code is structured. Especially so if this relaxed attitude brings along more developers. Some developers might find it easy to add a few extra attributes and proxy a key press event to a click handler than go mucking about with CSS to restyle a native button element. By allowing both paths, we naturally make more UIs accessible. I'm mostly thinking of the case where a common component is used throughout a product. Changing a span to a button or adding an href to an tag can have visually presentation effects that are non-deterministic, especially given a tangle of CSS across products. Using ARIA has zero display effects and its safer to make this changes on a large scale (we make hundreds of changes at a time).
Then say later, or during the maintenance phase of the code, someone else sees there is a handy anchor tag and adds a valid href. What then?
Valid point, although we can't know why an href is added. Maybe it's there for progressive enhancement. Clicking the button loads a modal dialog in the case where JavaScript exists, but navigates to a form in the absence of it. I think our task is to provide just enough advice to point to a good decision, but pull back just at the point of being acerbically prescriptive.
My thoughts on these issues are always evolving. I appreciate the debate. I'm using a bunch of these rules at large scale now, so time will tell what unforeseen behavior they engender. One thing I've already noticed is a growing incidence of tabbable elements inside tabbable elements. This is something we'll need to address at a high level of composition.
@jessebeach The debate is really cool indeed, thank you!
I like what you say, for sure. Guess it matters what one's current environment is. For me, it is projects where accessibility awareness risks getting dropped completely "due to it taking so much time". It makes is very hard to sell the "accessible applications don't take much more time to build" motto if the code is twice the size and takes twice as long to write because of ARIA. Not to mention that a large, respected accessibility auditor in the Netherlands will fail ARIA solutions if it is not the absolute only way to achieve the result.
(https://www.accessibility.nl/kennisbank/artikelen/wai-aria-en-toegankelijkheid Specifically the last paragraph. Unfortunately, there is no English version of the page so here is a google translated version which is ok-ish http://bit.ly/2rvCoZ2)
And as the developers in these projects often come from a background in server side dev, they also benefit from the cleaner HTML solution and not having to remember to add all the ARIA and extra event handlers. But these are often green field projects where CSS and test evolve alongside. In established projects, it is a different story.
In this environment, accessibility tends to happen more often with leaner and meaner HTML solutions. In a sense, dogma becomes pragma here LOL. But that said I wish I could claim a high a 100% success rate with this approach, so that, in itself proves it is not the holy grail.
Especially so if this relaxed attitude brings along more developers.
I think our task is to provide just enough advice to point to a good decision, but pull back just at the point of being acerbically prescriptive.
These points are very hard to argue. Fully agree that this is indeed the way to go. Conceded.
However, I am finding it more challenging to bring along project managers, product owners, and designers. Once again a driving force for the You Shalt Write Less ARIA approach. However, I do admit that this battle should not be fought in a tool like this.
However, I am finding it more challenging to bring along project managers, product owners, and designers. Once again a driving force for the You Shalt Write Less ARIA approach. However, I do admit that this battle should not be fought in a tool like this.
We can use the strict vs recommended configs to enforce these world-views.
Yes!
This debate has been going on since _Netscape_ vs _Explorer 5_ and still a mess. What diffrent consortium or "standards" trying to do -is not anchored in the updated real world. Thats why things are removed, and returns.
Yes, no href should not be treated as _non-interative content_. Nope, role="whatever" is a informative tool, not standard expected behaviour. I do agree this is a type question, and approach the problem from that perspective. Embrace the type attribute to anchor-tags and mimic until we expand the semantic to this element. I mean, the target attribute wont die, couse we need it. (end of ...)
In this thread, _the button element_ is to prefer consortium-technical, but the button element cant be visually incorporated, in a way that satisfy the big audience. And clients dont pay extra to "build semantic components from scratch as long as satisfy the contract of semantic role and behavior".
Example, common CMS that churches or organisations can afford to use, spits a dropdown-menu with anchor tags within unordered lists. Those organisations has often an audiance in need of all those accessibilities this thread is all about. Adding top level links with no landing page within Wordpress menu system, should be easy to do correct. Without href -should be tabbed- and lead to next menu item. attribute Type button should accept space key down on no-href-element. Problem solved. In this case, free open source, blind users and the big audience is the winner. The wallet too...
What we all want is a better world. But the webmasters reflects the needs of both the market and the audience. Do not only folllow standards when they actually many times block the process of development. But they are important, and we all should _contribute_ a few minutes more each year to them.
Embrace the type attribute to anchor-tags and use them, now, even if your perfect site not HTML validate. Implement once for all in your enviroment an event-listener like a[type=button] and add cross-browser ECMA to it. You have to tweak anyway...
I'm not sure what you're suggesting - why would using a non-standard HTML attribute on anchor tags solve anything?
Most helpful comment
@dantix an
atag without a validhrefis not focusable as it is not seen as a valid link.Therefore
<a role="button" tabindex="0" onClick={someWeirdlyNamedClickHandler}>could also have been a
div. Theatag has no meaning anymore.Not only that, but a
buttonelement should also be activated byenterandspacebar, therefore it would also need a keyboard handler to fully act as a button.The idea here contravenes the first rule of ARIA https://www.w3.org/TR/aria-in-html/#rule1
Whereas it is totally possible to create a
buttonlike this, an accessibility checker should reflect the first rule of ARIA instead. In other words, just use a button :)