bbc / gel

https://bbc.github.io/gel
39 stars 15 forks source link

Linkable buttons #75

Open billthornton opened 5 years ago

billthornton commented 5 years ago

Hello!

I think this is slightly different than https://github.com/bbc/gef-docs/issues/59 but let me know if it overlaps.

I'm looking at a few of the use-cases where links are being used in place of buttons and trying to see if there is a general improvement that should be applied to them.

Tabs

One use-case are tabs that link to standalone pages, such as the date tabs on:

Some similar implementations offer links instead of buttons if JS is disabled, but that prevents a user from opening one of the tabs in a new browser tab (assuming such a feature is still useful to our users)

More toggle/link

Another use-case is the More toggle in the global navigation, which links to the footer page fragment to cater for users without javascript, with the JS enhancing it opening the 'More' drawer. This is read out as a link by assistive tech.

Pagination

Some usage of pagination may also be considered included in this if - when javascript is enabled - the pagination links change the content in the page rather than linking to a new page (although they may change the url and title tag which could mean a link is fine)


Looking through the current GEF documentation:


Would you agree that these tabs/toggles should be pronounced as buttons and not as links and function in the same way as buttons do (https://bbc.github.io/gef-docs/components/buttons-and-ctas/#recommended-behaviour)? Or should they still be links and maybe (for the tabs example) change the url and title tag?

There are a few options we can see to achieve this, but non seem ideal.

Any thoughts on the above?

At the moment I'm not trying to implement any of these patterns (with the exception of maybe the More button in the masthead) but looking at the interface and behaviour of generic Button and Link components that may be used as part of such a pattern.

micmath commented 5 years ago

There is a lot to unpack in the premise of the question, so forgive me if I miss some of the details in my response, but the button v link question is generally a simple one: if it goes somewhere it's a link, if it does something it's a button. There are of course lots of nuances to that in practice: is a form submission "doing something" (submitting data) or "going somewhere" (via a location header in the server response, once the data has been processed). But I think the general rule covers 90% of cases.

Another nuance is the single-page application -esque pages, where clicking a thing causes most of the content on the page to change: did the user just go somewhere, or was a new page loaded as a result of doing something? That's subject to interpretation, and there was a rule used by devs at the BBC that if 80% of the content featured on a page changed, it was considered a new page. Obviously arbitrary, but a rule is needed.

CTA's (the so-called "call to action") pattern is another edge case where the link is presented in a way that is visually similar to a button. This must be based on the assumption that sighted users don't really care what HTML element you used, they just want the result you're pitching to them.

But for screen-reader users I think it does matter, and the decision is not without impact: when to use a button and when to use a link. It would be puzzling to hear "submit form: link" or "go to about page: button".

Often a component is designed to use slow-path actions as a fallback, like an a link to a whole new page to display a single new paragraph of text, but the enhancement is to use JavaScript to make an asynchronous request and then update the existing page. In that case the fallback is obviously a link, whereas the enhancement becomes a button: you're no longer going somewhere to see that paragraph.

All of this was considered by @Heydon when the guides were written, but as I showed, some of it is subject to nuance. Are there specific, separate examples where you think we got it wrong?

billthornton commented 5 years ago

Thanks @micmath, that's a really good response to my question.

For us the main example was the More button in the navigation/masthead (https://bbc.github.io/gef-docs/components/masthead/#the-more-link) where it makes sense for it to be an internal link for non-js, but not the best pattern for a screen reader user with JS. We could switch it out to be a button in javascript, but unsure if this is the best idea.

There's an example of it causing confusion here: https://youtu.be/OUDV1gqs9GA?t=1043

Heydon commented 5 years ago

@billthornton @micmath The use of a same-page link here was an effort to make the control usable in the absence of JavaScript (I felt this was important, especially in the case of the main navigation). One other advantage is that, by saying "same-page link" in screen readers they can anticipate a change of focus. However, a similar notion could be communicated with aria-haspopup="true" on a button. But then the focus can only be moved with JavaScript.

micmath commented 5 years ago

Love the video. @billthornton. Here's a little-known-factoid, I actually was the front end dev that built that damned More button in Barlesque (as it was known at the time). So I feel personally invested in this discussion suddenly :-)

But that is an error that proves the rule actually. The way the More menu was designed to work is that it really was an in-page link, that properly just moved focus to another part of the page, a list of further options located just above the footer. But in the JS-enabled enhanced version of the page we wrote a script to move that list of links from the bottom of the page up into a hidden drawer. And the enhanced experience for the JS-blessed was that they got a nice list of navigation links, and a slidey drawer effect that held the overflow links.

So under that design the un-enhanced thing really is a link (although an in-page one). Where we went wrong was in not upgrading it to a button for the enhanced experience. And the proof that this was a Bad Thing is in your video. Screen reader users actually know when you get the semantics wrong, and it actually can cause confusion.

billthornton commented 5 years ago

I definitely understand (and agree with) the non-JS behaviour! As noted in the original post, it's easy for us to Replace the anchor elements as buttons when JS activates. Would that seem like a reasonable solution to provide the best experience for both non-js and js?

micmath commented 5 years ago

I'm hesitant to answer without actual data, but the video makes pretty strong case. I'd say that if an element walks and talks like a button when JS is active then it should be a button when JS is active.

Heydon commented 5 years ago

@billthornton @micmath I don't think there is a behaviour/semantics mismatch since the same-page link works as expected. Whether a button would be more appropriate/expected in any case is arguable, though. I have a hunch that users are generally more familiar with same-page links than aria-haspopup buttons, since the first is a much longer established paradigm.

The only other way to do it with JS would be to not move focus upon activation. But, in this case, there are elements between the button and the disclosed element, which would lead to confusion. aria-controls would mitigate this, but it is only supported in JAWS.

If we switched from same-page link to aria-haspopup button, we'd essentially be switching from two different, but equally technically sound, solutions for the same focus management issue. I'm leaning towards not bothering, since it increases complexity in the component.

micmath commented 5 years ago

I admit, I don't fully understand the complexities of all the arguments being made here, but @Heydon are you saying that because, when the element is clicked, focus moves to another part of the page, then it is semantically equivalent to an in-page link, and therefore using an A ELEMENT is valid?

The fact that the other part of the page is hidden, and slides open to be visible when it receives focus is a red herring in that case, and the if it does something rule doesn't strictly apply?

Sorry, trying to wrap my brain around this!

Heydon commented 5 years ago

Yep, that's what I'm thinking. But you raise a good point about the disclosure behavior (I was still picturing the "everything open" no JS mode for some reason!)

That considered, I think the most robust and least intensive enhancement would be to add role=button, aria-haspopup=true, and the space bar activation support.