[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)