Hacker News new | past | comments | ask | show | jobs | submit login
Why using anchors as buttons sucks (plus.google.com)
50 points by tkazec on Feb 5, 2012 | hide | past | favorite | 26 comments



I hate to be critical, and maybe I'm missing something, but this essay didn't read well at all. Sounded like somebody who didn't fully understand what they were doing thrashing around.

We use anchor tags as buttons any more because clicking on buttons should (eventually) change the href.location. That means, yes, right-click should work just fine, opening up a new window with your action applied to the current state. Don't look at buttons like Javascript events. Rather look at them like code that changes the URI that then kicks off Javascript events. It's a subtle difference, but it's very important. An anchor as a button isn't the same as a button because they're two completely different things. Your mental model of each should be different.

I don't see where there's much of a mystery or rant here, but maybe I missed it.


It really just depends on the context: In a web app (the example in the essay) or Chrome extension, traditional navigation mostly falls away, leaving something almost entirely controlled by JavaScript. Buttons and links have two distinct styles and places to be used, but in a web app they usually functionally do the same thing. In Bootstrap, the issue was how to make links that look like buttons also behave like buttons, which all the issues still apply to.

Once someone brought up the keyboard issue in my pull request, I researched for a while, and then made the post once I angrily realized the full extent of the problem.

If you need an example app that uses both buttons and links, here: https://chrome.google.com/webstore/detail/mghenlmbmjcpehccoa...


Actual buttons annoy me. I like navigating around using just the keyboard, so a lot of the time I just do a search for the link I want to click (ctrl-f on Chrome or ' on Firefox) then just use enter to click the link. This works great when the button is actually just a styled link, but does not work at all with an actual button.

Of course, I'm indubitably in a tiny minority, but it's still something to note.


On a similar note to this, I generally like to open links in new tabs, so that I can refer back to the original page without losing my place, or to refer to the linked content after I finish on the current page. This does not work when you are using styled buttons, or pages which rely heavily on JS/AJAX to do their thing. Inevitably in this case, I must navigate away from the original page, look at the content and then use back, hoping that I return to the correct location.

Notable examples of this include the Facebook "Show more comments" link, g-mail's email links and "Add to Cart" buttons which redirect away from the product page.


I too use search and enter to navigate quite often. But I also use middle mouse button to open targets in background. This doesn't work when there is no target. And I think every link should have an target. So buttons are all right if they just modify the content of the page. Buttons for opening new pages are bad. Anchors opening new pages (usually sized pop-ups) just by javascript, having no real target are horrible and I want to punch someone responsible every time I see something like that.

Funny enough, the google plus linked above is horrible at this.


Okay, but buttons are intended to do something, not for navigation. If someone is using a button to send you somewhere, they are doing it wrong. That's what anchor tags are for. Basically, buttons imply an action where as anchor tags imply navigation. If you are running into people using buttons as navigation, it's not the buttons fault!


By "navigating" I don't mean just moving from page to page but rather interacting with the particular page. So even if your button only does something on the current page, I would like it to be a link so that I don't have to click on it.


> if your button only does something on the current page

That doesn't make any sense. First, the current page doesn't matter. Secondly, "doing something" doesn't define what "something" is. Finally, your complaint is having to click on the button, implying that you have to click on a button to activate it.

Sorry, your just being very confusing, using words and terminology you don't seem to be familiar with.


Perhaps my wording was not entirely clear--what I meant was, regardless of what the button does, I want to activate it without tabbing or clicking, just using search. This works well with anchor tags, but does not work with buttons.

I meant navigating in the sense of moving the viewport and mouse around a static page rather than moving from page to page.


Great point, I hadn't thought of that. Buttons are so finicky :(

On a related note, I wonder how screenreaders handle buttons? I'm guessing/hope they read the labels, but if they don't...


Link hinting and following scripts in many vim-like browsers allow you to click or focus buttons by an index or the button text. Example in luakit: http://i.imgur.com/qTOPz.png


Try any of the vim keybinding plugins if you like keyboard navigation. I use vimium with Chrome.


Why don't you add href='#' and return false from the click event. Nothing gets added to the history that way.

Better yet, add a href='/uri/to/script' as a fallback in case the user has JS disabled.


I was under the impression this (href=uri, js fallback) was the accepted standard, is it not?


It is, the comments on the blog say as much as well. Use href="#" if a link makes no sense (anything UI-related and ephemeral, basically).


Even many UI-related items could have sensible URL, e.g. href="#show-widget" (and read location.hash and perform that action when page is loaded).

The href is not only for JS-less browsers, it's also for links opened in new tab or saved in browsing session.


You really should not return false from event handlers. Returning false is equivalent to calling both preventDefault() (that's what you want) AND stopPropagation()

By stopping propagation, you break delegation and make it impossible at worst and very random at best to add another handler to the same event.

Just use preventDefault o stop the browser from following the link.


  Returning false is equivalent to calling both preventDefault()
  (that's what you want) AND stopPropagation()
This is so in jQuery. In basic Javascript "return false" does not stop the propagation. See http://stackoverflow.com/questions/1357118/javascript-event-...


For a moment there I was trying really hard to understand what he was complaining about. His post made very little sense to me as it was written. I guess because I haven't even come close to experiencing his "problem".

Especially since I looked over the pull request he mentions and the explanation as to why href="#" is used is right there in front of his face.

Plus, what's with all the hate for href="#"? Are some people so anal about their code they can't leave one simple little thing in place that makes life easier for them?


>what's with all the hate for href="#"? Um, there was a section of my post explaining everything wrong with it, which was also further discussed in the G+ comments.

Of course I understand why keyboard accessibility (a benefit of href="#") is a good thing, that was a main point in the post: There's no solution for adding "buttons" (in the functionality sense) that look like standard links without major drawbacks, like a lack of keyboard control.


You missed not being able to disable them without javascript if you set the href, pretty big disadvantage to miss. I vaguely remember IE might support the disabled attribute, but it doesn't actually work properly. That might just be 6 though. I also have a feeling there are other weird side effects to not setting a href attribute on an anchor, but maybe it's just that.

This doesn't feel a very comprehensive or well researched post, especially as you didn't know about e.preventDefault() which afaik is standard practice these days, seems a fairly ballsy thing to ask bootstrap to do when you don't really seem to know much about it.

Then again I guess if you don't question these things, you never find out!


I think in situations where you want to use a "button" (in the functionality sense) that looks like a link, you probably won't need to disable it—the two styles don't really mix for the most part, though I'm sure I've seen it done somewhere.

I know what e.preventDefault() is and when and how to use it, just simply didn't think of it when trying to find solutions. It was promptly pointed out in the G+ comments, but there are still major drawbacks to that approach.

Either way, it was well past the asking Bootstrap to add this phase by the time I wrote the post.


here's what i do, i use button tag where it has to look like a button and use a link where it has to look like a link. Also if link requires an eventhandler instead of href change i simply omit href attribute altogether and write my css to apply to a tag irrespective of weather it has href attribute or not. problem solved.


this will cause the tabbing issues mentioned in the article


well if i want something to look and feel like a button, i won't ware about tab navigation. its a button after all. Its like saying i can't use a div to make it look like a button because it cannot be accessed through tab. Its a div, not a link. If i want tabbed navigation i will use a link not a button.


You create an anchor like you would, you write a proper onClick handler that does your favorite animation and then sets the window.location to the href or if you don't want to figure this out, you could just use something like jQuery UI button and you are happy.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: