[HN Gopher] Links are not buttons (2013)
       ___________________________________________________________________
        
       Links are not buttons (2013)
        
       Author : Fiveplus
       Score  : 80 points
       Date   : 2021-04-08 10:20 UTC (1 days ago)
        
 (HTM) web link (karlgroves.com)
 (TXT) w3m dump (karlgroves.com)
        
       | tootie wrote:
       | His main points are about accessibility but there's a lot of
       | overlap between accessibility and SEO. Google needs semantic tags
       | to understand your site. It will treat any <a> as navigation and
       | won't do the same for <button> or any other approach. The basic
       | premise that <button> is for CTAs and <a> is for navigation is
       | the golden rule. You can style either anyway that you want.
        
       | ironmagma wrote:
       | Honestly, if you spend energy worrying about this issue, it's
       | like using a bucket to bail water out of a sinking cruise ship.
        
       | lights0123 wrote:
       | And never use href="#" or href="javascript:void(0)": middle-
       | clicking on it will lead to unexpected results.
       | 
       |  _I 'm looking at you, Hacker News_
        
       | blackbrokkoli wrote:
       | I agree with the author...partly.
       | 
       | Sure, <divs> and <spans> are not buttons and should not ever be
       | used as those. Knowing and adhering to standards, especially when
       | they are there for accessibility, is an excellent thing.
       | 
       | But in some cases, making links links instead of buttons (and
       | similar scenarios) just means exposing internal works to the
       | user. Say I have a SaaS with the classic "GET STARTED NOW" button
       | on the landing page. Now I change my tech stack from something
       | classic like Rails or Lavarel, where "get started" probably means
       | a link to the signup page to some fancy JavaScript which triggers
       | the action of overlaying a signup form. Would you really agree
       | that the HTML for my "GET STARTED NOW" button should change
       | depending on what kind of method my app uses?
        
         | minitech wrote:
         | > Would you really agree that the HTML for my "GET STARTED NOW"
         | button should change depending on what kind of method my app
         | uses?
         | 
         | Indeed not! "Get started now" should always be a link. If you
         | want to give it fancy behaviour, you can attach an event
         | listener to it that cancels the default one (mind the modifier
         | keys).
        
         | mwcampbell wrote:
         | > some fancy JavaScript which triggers the action of overlaying
         | a signup form
         | 
         | Don't do that. Having the signup form be its own page is
         | simpler and less cluttered, thus better for the user.
        
       | eximius wrote:
       | Buttons do something.
       | 
       | Links go somewhere.
       | 
       | Don't cross the streams.
        
         | Ronson wrote:
         | This is really the best advice in a nutshell.
        
         | marcosdumay wrote:
         | There are many applications where "doing something" technically
         | means going into another URL, and interacting with it. Those
         | should be links anyway (the technical meaning beats the UX
         | one), but I see no problem on styling them as a button.
         | 
         | Just don't style buttons as links.
        
           | thex10 wrote:
           | > Just don't style buttons as links.
           | 
           | My designers keep doing this, sadly.
           | 
           | I mean, they don't _realize_ they're doing this. But they
           | will have an element on the page where a user clicks on it to
           | do some action (not navigate to another page), and they will
           | style it to match the site's links. It unfortunately seems to
           | be a very popular pattern.
        
         | commandlinefan wrote:
         | > Buttons do something
         | 
         | > Links go somewhere
         | 
         | Well... all the way back to HTML 1.0, form submission buttons
         | also "went somewhere". It was quite a while before the concept
         | of any interaction not reloading the entire page came along.
         | There's nothing wrong with buttons that go somewhere, and a lot
         | of the web is designed around this.
        
           | giantrobot wrote:
           | No, form submit buttons _did something_ i.e. submitted the
           | form. While this had the effect of going somewhere the
           | expectation was straight forward and obvious. Using forms as
           | links was roundly advised against.
        
         | [deleted]
        
       | lfowles wrote:
       | One pet peeve of mine with the button-ish links is that sometimes
       | they only work if I click _on the text itself_.
        
         | dheera wrote:
         | This is usually caused by lazy devs who use
         | <div class="mybutton"><a
         | href="javascript:dosomefoo();">foo</a></div>
         | 
         | instead of                   <div class="mybutton"
         | onclick="dosomefoo();" style="cursor:pointer;">foo</div>
         | 
         | It's also possible they were trying to support old versions of
         | MSIE in the former.
        
           | bobthepanda wrote:
           | The latter is not WCAG compliant.
           | 
           | Really the <a> tag should wrap the div, not the other way
           | around.
        
           | runarberg wrote:
           | Please don't do the latter. It breaks keyboard accessibility.
           | Users that don't have a mouse have no way of clicking this
           | fake button.
           | 
           | This MDN article[1] will help you find the correct attributes
           | and behaviors to make your <div> fully accessible with a
           | button role.
           | 
           | 1: https://developer.mozilla.org/en-
           | US/docs/Web/Accessibility/A...
        
             | dheera wrote:
             | Well shit ... okay ... if they made it easier to code web
             | pages maybe we'd have a more consistent experience. It
             | seems if you do the intuitive thing you always break it for
             | one user or the other, and it's designed such that you have
             | to do a non-intuitive thing to serve everyone.
        
               | jaywalk wrote:
               | Intuitiveness is in the eye of the beholder. I'd argue
               | that if you're experienced with accessibility, doing
               | things the "accessible way" becomes _more_ intuitive.
        
               | a1369209993 wrote:
               | > if you do the intuitive thing you always break it for
               | one user or the other
               | 
               | No, if you do the intuitive thing you get:
               | <a href="http://whereever/">foo</a>
               | 
               | which works fine for every user.
        
               | lukeschlather wrote:
               | You have to follow the specifications. None of this is
               | remotely intuitive if you haven't read and studied the
               | specs. If your intuition is wrong that's probably because
               | you've been doing "whatever seems to work" rather than
               | reading the specs and following them.
        
               | bobthepanda wrote:
               | If you want to have the entire div act as a link, the
               | link should cover the div, not the other way around.
               | What's not intuitive about that?
        
       | paxys wrote:
       | I think 90% of the misuse arises from devs not realizing that
       | they can use a <button> or <a> (or whatever else is correct in
       | that context) and still style it however they want.
        
       | mr-wendel wrote:
       | The problem is that links provide a very reliable way to perform
       | a controlled HTTP request to get a dynamic response from the
       | backend.... without using JavaScript. I love JavaScript, but if
       | device reusability is a serious concern then JavaScript is the
       | elephant in the room, not this topic. Is it available? What
       | version is supported? What quirks does the engine have? To be
       | fair... it was posted in 2013 :D.
       | 
       | The only working alternative (editing if I stand corrected!)
       | using buttons is to make them form buttons. Now otherwise
       | intuitive behaviors (e.g. forward/back, refresh) are laden with
       | "you're about to resend data!" warnings that completely break the
       | flow.
       | 
       | To me, it makes perfect sense why this trend evolved. Most people
       | agree with the underlying premise about user expectation on
       | button vs link. Dressing links up as button is a direct response
       | to that. I understand the technical arguments, but users care
       | what it looks like and how it behaves, not how you implemented
       | it.
       | 
       | Edits:
       | 
       | - Yes, you can use <form method="get"...> without scary browser
       | warnings. It just gets a but ugly if you have lots of buttons, as
       | each needs its own form wrapper.
       | 
       | - 303 redirects to POST request are a handy pattern to be aware
       | of no matter what :)
        
         | crazygringo wrote:
         | And that doesn't even get into CSS styling.
         | 
         | You know a link starts with the exact same height and font that
         | surrounds it, and then you can style it to predictably know
         | exactly what you'll get.
         | 
         | A button shows up in a new font -- a font of _unknown_ size at
         | that, because it utterly ignores the font size of its container
         | -- with extra height that introduces line-spacing issues -- and
         | all of this by totally unpredictable amounts because it varies
         | radically across _both_ browser and platform. And if you want
         | to undo all that styling, have fun delving into the quirks of
         | each browser of how to do so.
         | 
         | If you're building something simple where appearance really
         | doesn't matter, then sure throw in a button. But if you
         | actually want to have predictable results, then the only
         | straightforward way is with a link you style.
        
           | minitech wrote:
           | .button {         all: unset;         /* continue styling */
           | }
        
         | nathcd wrote:
         | > The only working alternative (editing if I stand corrected!)
         | using buttons is to make them form buttons. Now otherwise
         | intuitive behaviors (e.g. forward/back, refresh) are laden with
         | "you're about to resend data!" warnings that completely break
         | the flow.
         | 
         | If anyone is looking for a solution to this, you can respond to
         | a POST with a 303 (See Other) redirect. There's even a
         | Wikipedia page for this pattern:
         | https://en.wikipedia.org/wiki/Post/Redirect/Get
        
         | Groxx wrote:
         | <form action="whatever" method="get">
         | 
         | or has that not been around for long? I haven't found anything
         | stating when it first arrived.
        
           | tesseract wrote:
           | Since HTML 2.0 at least. Before that I think the method was
           | specified as part of the action attribute.
        
           | jdfellow wrote:
           | Given that the default method is get, and you have to set
           | method=post for otherwise, I'd suspect it's been around
           | longer than method=post.
        
         | cryptonector wrote:
         | It would be really nice to have a button that doesn't navigate
         | away and doesn't require JS.
        
         | mr-wendel wrote:
         | Can't edit now, so also adding this: you can't nest forms which
         | may unnecessarily complicate some layouts
        
           | Conlectus wrote:
           | Noting that you can use form="my-id" to have the fields
           | outside the form tag, though that might be the complications
           | you mentioned.
        
         | Kwpolska wrote:
         | > The only working alternative (editing if I stand corrected!)
         | using buttons is to make them form buttons. Now otherwise
         | intuitive behaviors (e.g. forward/back, refresh) are laden with
         | "you're about to resend data!" warnings that completely break
         | the flow.
         | 
         | You can make a form with method="GET" that doesn't do this,
         | works the same way a link would, and can send form data.
        
       | dheera wrote:
       | Big pet peeve: Web apps where some buttons look like buttons and
       | some buttons look like links. Everything that initiates an action
       | of some sort should look the same, damnit.
        
         | dmitriid wrote:
         | I give you one of the biggest abusers: Google's Material
         | Design, https://material.io
         | 
         | Each design iteration of that page keeps using buttons for
         | links, links for buttons, links that look like plain text etc.
        
         | dredmorbius wrote:
         | That ship has flown on some very long legs.
        
         | runarberg wrote:
         | I see your point, and used to share it. But recently I've
         | worked with professional designers that use this pattern quite
         | a lot and my mind is now changed. For example I see nothing
         | wrong with a link to e.g. a creation form looks like a button,
         | nor is nothing wrong with a destructive action to have the
         | lower visual weight of a link (e.g. delete this repo; flag this
         | comment; etc.).
        
           | anoncake wrote:
           | How did they change your mind?
        
           | dheera wrote:
           | annotating from a public sample image:
           | 
           | https://i.imgur.com/VwD8DWi.png
        
         | josephwegner wrote:
         | _Looks awkwardly at the HN "flag" button_
        
       | [deleted]
        
       | superkuh wrote:
       | Everything is a button now that javascript applications have
       | replaced HTML documents. And there are no such things as anchors
       | or links anymore. They are not URLs but instead triggers for more
       | javascript execution. We're, unfortunately, well past this minor
       | problem and onto much more serious ones that eclipse it.
        
         | lunfard00 wrote:
         | In 2013 most people were happy with every new shiny app, and
         | now that web is looking more and more like an app, is that an
         | issue?
        
         | robertoandred wrote:
         | You're not understanding the semantic and UX reasoning behind
         | this article. JavaScript has no relevance to it at all.
        
         | chociej wrote:
         | TBH I don't care too much what someone does with a button or
         | link, but if hold Ctrl and it doesn't open in a new tab, I'm
         | gonna be grumpy.
        
           | jibbit wrote:
           | Twitter seems to have recently (partially) given up on <a>
           | tags, meaning i can no longer right-click to open in a new
           | tab - it is infuriating
        
             | anthk wrote:
             | https://nitter.net
        
               | dredmorbius wrote:
               | Chronically rate-limited, use an alternative.
               | 
               | (I could mention one that works, but that will eventually
               | of course just compound the problem. So my secret fishing
               | spot remains secret ;-)
        
               | blewboarwastake wrote:
               | You can use this extension:
               | https://github.com/SimonBrazell/privacy-redirect and use
               | the "use a random instance" option
        
           | Kelamir wrote:
           | Hold control to open links in new tabs?! Woah! That's so much
           | better than using middle mouse button, which is just
           | suffering. Thanks chociej :)
        
             | wussboy wrote:
             | I have always used Gesturefy to make right-click and drag
             | down to open in a new tab. I don't know where I originally
             | picked up this gesture...maybe Opera in 2003? But I've
             | always loved it and use it a hundred times a day.
        
             | Ashanmaril wrote:
             | Why is a 2-handed input better than a 1-finger input?
        
               | marcosdumay wrote:
               | It certainly depends on your hardware. The GP is just
               | rooted in a completely different experience than yours.
        
             | kaibee wrote:
             | I have one of those fancy gamer mice (Logitech G700S) and I
             | bound the most prominent thumb button to middle-click.
             | Haven't looked backed, making scroll-wheels clickable was a
             | mistake.
        
               | hypertele-Xii wrote:
               | Scroll wheels themselves are a bad implementation of a
               | good idea. I bought a cheap USB volume control knob and
               | used AutoHotKey to rebind volume up/down events into
               | wheel scrolls. Productivity increased like crazy!
               | Scrolling is no longer a chore, it's a pleasure. I even
               | went the extra mile and coated it with rubber for a good
               | grip.
        
         | anhanhanh wrote:
         | That's just not true. Well known and widely used libs such
         | react-router are an evidence of that.
        
         | ehnto wrote:
         | It's tricky to balance user expectations with semantic HTML now
         | that the web has evolved so far.
         | 
         | The easiest example I have from my industry is a product card
         | in a grid of products. There really is no correct spot to link
         | it in some designs, but the user expects to click any part of
         | the box and be taken to the product page. So you wrap the whole
         | box in an anchor tag, which has its own host of problems.
         | 
         | As you said though, that is a bygone problem, this ship has
         | sailed in the land of SPAs. Even a simple blog is an SPAs these
         | days.
        
           | ravenstine wrote:
           | User expectations, or executive expectations?
           | 
           | In my experience, the effective expectations of users are
           | remarkably low. If you were to survey users, you'd get the
           | impression that users are very particular. In reality, users
           | tolerate all sorts of things that most of us on HN would
           | consider primitive or nearly broken. If most web applications
           | actually relied mostly on constructs provided by the
           | browser/DOM rather than JavaScript, the average user wouldn't
           | notice or care.
           | 
           | But there are product owners who power trip on the
           | possibility that _they too_ could be just like The Google, so
           | they want everything to be unnecessarily animated and
           | dynamic. On top of that, many of them want Silicon Valley
           | programming at San Fernando Valley prices, so not only do
           | they request that their web applications be unnecessarily
           | complicated, but the junior devs they hire are given no
           | direction and the code gets bloated, wrecking performance
           | (which matters more than  "delightful" UIs).
        
             | ehnto wrote:
             | I am entirely inclined to agree with you. It is definitely
             | perpetuated by project stakeholders, even developers
             | wanting to try new tech.
             | 
             | But now that we have spent years training eCommerce user
             | behaviours you do find that people will be busy clicking
             | everything but the product title, arguably the most
             | semantic place to put the anchor, so it may take a user a
             | few goes to get where they're going. The user might not
             | care but many of the project stakeholders do.
             | 
             | While I am an evangelist of a utilitarian, semantic web, I
             | feel it's an idealism that hasn't survived it's encounter
             | with the real world in commercial software. We went from
             | being worried about javascript image sliders being too
             | heavy, to making the client compute and render the entire
             | application, in about 8 years. I think the trajectory is
             | clear, and I doubt we'll have a watershed moment where the
             | whole tree of stakeholders suddenly wants less.
        
           | marcosdumay wrote:
           | > So you wrap the whole box in an anchor tag, which has its
           | own host of problems.
           | 
           | Looks like the correct solution to me. What are the problems?
        
             | guntars wrote:
             | You can't have interactive elements inside anchor tags.
             | Very often the box will have some additional buttons for
             | different actions, like "Save for later". I like the
             | approach of using an anchor tag just for the title and have
             | another click handler on the box to serve as a fallback,
             | but you don't get to ctrl-click on the box anymore.
             | Alternatively you can have the link be a sibling of the
             | buttons in the DOM, but visually cover the whole box and
             | appear behind the buttons. As you can imagine, any solution
             | like this is going to add more work and be a potential
             | source for bugs.
             | 
             | This is one of the two things that I really wish browsers
             | would fix, instead of cramming in completely new features.
             | The second is how hard is it to make popovers work
             | correctly, especially inside scrollable containers.
        
               | marcosdumay wrote:
               | Oh, that's a problem.
               | 
               | That really looks like a task for image maps, except that
               | they only work for images. Yeah, I agree with those two
               | problems.
        
           | dmitriid wrote:
           | https://inclusive-components.design
           | 
           | Namely, cards: https://inclusive-components.design/cards/
        
         | anchpop wrote:
         | The FUD about SPAs and Javascript on HN is insane. Here's my
         | personal site: https://chadnauseam.com/. It's a SPA. It loads
         | fast. There are such things as anchors and link (inspect
         | element if you like). They have URLs and you can ctrl-click to
         | open in a new tab.
         | 
         | (The biggest proble with it is that I've been playing around
         | with some js to animate a fade-in effect on page load, and it
         | seems a little laggy and makes the site not work with
         | javascript disabled. If I can't fix those issues I'll probably
         | remove that in a few days.)
        
           | [deleted]
        
           | Ashanmaril wrote:
           | The Discord/Twitter "buttons" on your site actually highlight
           | one of the issues here. You can't open them in a new tab, or
           | hover to see where they're taking you. They also don't make
           | the mouse react properly to being on something clickable
           | (though that could be fixed with a `cursor: pointer` style)
        
             | tshaddox wrote:
             | Which is actually a clear illustration of the point: that
             | you have to go out of your way to make "link-like" things
             | that aren't actual links. Clearly whatever framework or
             | rendering library the site is using supports client-side
             | navigation via real working anchor tags. But for some
             | reason, they decided to not use those for the social media
             | widgets.
        
               | [deleted]
        
           | jraph wrote:
           | It's a blank page for me. It does not load at all.
           | 
           | I want my browser to display documents, not to run code. I
           | don't want documents to be apps. The browser already has very
           | sophisticated code to render documents well.
           | 
           | Unless I am really running an app - then this is somewhat
           | fine to use the browser as a runtime. I'll make sure to only
           | run open source apps with it, unless I really don't have a
           | choice.
           | 
           | edit: wait, your page is so close to render perfectly without
           | JS! You can fix this by avoiding opacity:0 in the HTML!
        
           | cookiengineer wrote:
           | I'm not sure you are aware that everybody that activates JS
           | just to see this type of content (which can be done in a
           | static html only manner) will be heavily disappointed when
           | they've loaded your page.
           | 
           | It's like waiting to load a WebGL demo of a damn teapot.
           | Afterwards you have a negative impression, such as me now
           | thinking of chadnauseam, that I now think has no effing clue
           | about webdev if this person can't create two damn paragraphs
           | without a JS framework.
           | 
           | If you throw a heavy JS framework on a website, make sure the
           | content is at least as heavy. If the content is two
           | paragraphs of text, why would you disappoint users so much
           | when they visit from mobile?
        
           | bobbylarrybobby wrote:
           | When I hover over most links on your page, I see the link URL
           | in the bottom left corner of the browser window. But when I
           | hover over the discord and twitter buttons, I don't. And when
           | I command-click those buttons they _don 't_ open in a new
           | tab.
           | 
           | So you used buttons (spans?) instead of links and broke the
           | very functionality the article talked about.
        
             | throwaway8581 wrote:
             | > _And when I command-click those buttons they don 't open
             | in a new tab._
             | 
             | One of my greatest annoyances. I'm an open in new tab guy.
             | When I see this annoying pattern I end up clicking, middle
             | clicking the back button (only possible on desktop), then
             | switching the tab positions, so I can get the correct
             | outcome.
        
               | tacotime wrote:
               | I'm a regular laptop user and I often use this trick. In
               | Windows you can ctrl+click the back button to pop open a
               | tab for the previous url, I'd guess command+clicking the
               | back button does the same on a Mac.
        
               | throwaway8581 wrote:
               | Thanks. I didn't know that. I usually just map three
               | finger tap to middle click.
        
               | a1369209993 wrote:
               | > middle clicking the back button
               | 
               | TIL, apparently. Also, middle-clicking refresh opens a
               | new copy of the current page. So much for GUIs being
               | discoverable. Thanks.
        
               | runarberg wrote:
               | To be fair, your browser probably has a history menu
               | option in the top menu that opens a sidebar with your
               | recent history. You can probably right click the top page
               | and click "open in a new tab". This is highly
               | discoverable and does the same thing (just in more
               | steps). You can also select the text in your URL bar,
               | right click and copy, then open a new tab the usual way
               | and paste the URL there. Also the same results but highly
               | discoverable with extra steps.
               | 
               | As far as I know highly discoverable means there is no
               | hidden functionality, not that every shortcut is
               | advertised.
        
           | Isognoviastoma wrote:
           | This is great example of what is wrong with many SPAs. They
           | should not be applications in first place. Why is it using
           | tons of JS to display few paragraphs of static text? It could
           | be hosted as static html pages. It also kind-of works in
           | lynx, but totally don't in FF without JS.
        
           | coldpie wrote:
           | > The biggest proble with it is that I've been playing around
           | with some js to animate a fade-in effect on page load
           | 
           | Yeah, there's no reason do this. It's text. Just let it
           | render. KISS.
        
           | bestinterest wrote:
           | I'm not sure its FUD, your main page takes 63.5KB + 38.7KB
           | for the gatsby reactified framework? + an extra 39.8KB in
           | some js bundle and another 51.7KB in some other js bundle.
           | 
           | Also you end up thrashing 5MB of browser storage when I
           | hovered a link check out Application -> Storage in Chrome.
           | 
           | Maybe I'm crazy but your page should not need that much, your
           | site is making 20 requests to resources (thankfully you have
           | http2) and the longest request took about 7s on a slow 3g
           | connection. For comparison here is Tom MacWright's page
           | https://macwright.com/ which does 2 requests at 14kB total
           | taking 2.3s on a slow 3g connection.
           | 
           | I will give you the prefetch trick is superslick in the
           | Gatsby framework for blogs but no reason to have a whole
           | React framework around it. Just use https://instant.page/
           | 
           | I say all this and I do love the component nature of React
           | and SPA's (I love Svelte the most at the moment) but it does
           | really not feel like the right tool for 99% of personal
           | blogs.
        
           | dmitriid wrote:
           | This is a page that displays nothing but static text.
           | 
           | - It does 71 requests
           | 
           | - It loads 2 MB or resources for this static page
           | 
           | - Saves at least 6.7 MB of data in storage on load, no idea
           | where that comes from (service workers maybe?). It jumps to
           | ~16 MB on page refresh
           | 
           | - Running Lighthouse on your website gives 2.9s until first
           | contentful paint. 3 seconds to display less than a kilobyte
           | of text. And that's for the front page. It's significantly
           | worse for longer pages.
           | 
           | - And on top of that it has buttons-for-links for discord and
           | twitter (that are also, funnily enough, removed by ad
           | blockers like AdGuard)
           | 
           | Oh yeah, I see how the "FUD about SPAs" is in reality fully
           | justified criticism.
        
           | minitech wrote:
           | > It's a SPA.
           | 
           | Yeah, but even ignoring all the SPA-caused bugs that other
           | people pointed out - why? It's just static content.
        
           | boring_twenties wrote:
           | It certainly loads fast -- in fact, I get the completely
           | blank page pretty much instantly.
           | 
           | I do appreciate that it's at least a black blank page and not
           | a bright white one, though.
        
           | bobthepanda wrote:
           | Couldn't you just do fade in with CSS?
        
       | _greim_ wrote:
       | I think the converse--buttons are not links--doesn't get enough
       | attention. The litmus test is that if clicking it is supposed to
       | navigate, you should also be able to shift+click or middle-click
       | to open it in a new tab, or drag it up to your toolbar to make a
       | bookmark.
        
       ___________________________________________________________________
       (page generated 2021-04-09 23:00 UTC)