Links are not buttons (2013)
karlgroves.com
karlgroves.com
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 :)
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.
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
The author argues to NOT use fake anchor tags like <a href="#"> and then add functionality to it via JavaScript. Instead you should use <button type="button">.
Either way, JavaScript is required.
What you’re suggesting means your link is actually a link to another page, which works without JavaScript and that’s not the point of the article.
<form action="whatever" method="get">
or has that not been around for long? I haven't found anything stating when it first arrived.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.
.button {
all: unset;
/* continue styling */
}Well, very happy to know that's no longer the case then, thanks! One more thing in CSS that's finally been addressed.
(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.)
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.
So you used buttons (spans?) instead of links and broke the very functionality the article talked about.
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.
TIL, apparently. Also, middle-clicking refresh opens a new copy of the current page. So much for GUIs being discoverable. Thanks.
As far as I know highly discoverable means there is no hidden functionality, not that every shortcut is advertised.
However, this convention has been muddied a lot on the Web in the past few years, but I still like to follow it.
- 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.
Yeah, there's no reason do this. It's text. Just let it render. KISS.
I do appreciate that it's at least a black blank page and not a bright white one, though.
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!
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?
Yeah, but even ignoring all the SPA-caused bugs that other people pointed out – why? It’s just static content.
(I could mention one that works, but that will eventually of course just compound the problem. So my secret fishing spot remains secret ;-)
The golden rule is that if a button opens a link to a page that has its own URL, it should be a plain anchor tag.
You can apply whatever JavaScript on top of it to “ajaxify” it, as long as you ignore altered clicks (ctrl, cmd, shift, etc)
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.
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).
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.
It’s literally 2 loc, it doesn’t affect accessibility and it’s using JavaScript for what it was meant : adding some optional convenience.
I realize I’ve not done real server rendered sites for years, but adding good old « optional convenience » JS without jQuery and broken browsers, but with ES6, modules, and maybe WebComponents would probably be a really pleasant experience.
https://css-tricks.com/block-links-the-search-for-a-perfect-...
Looks like the correct solution to me. What are the problems?
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.
It is what is normally done but it isn't perfect.
That really looks like a task for image maps, except that they only work for images. Yeah, I agree with those two problems.
I'm looking at you, Hacker News
Some break middle clicking but I can still right click and select "open in new tab" from the menu. But there's others that don't even allow that. It's awful.
This has some obvious advantages for some use cases: preserving local state, fast refresh, less duplicate data fetching from the server, etc
Downside is those are not links and opening in a new tab doesn’t work by default. It’s fixable in most cases, but additional work.
Luckily modern frameworks like Next.js make it easy to build apps and pages that have best of both worlds.
The entire thing makes me feel dirty. The data collected is never even looked at. And yes, it breaks middle-click and right-click behaviour.
Anyone hiring Rails devs anymore? ;)
I actually did this mistake when starting with React, now I try to make everything as close to a native link as possible.
IIRC, that’s a very old (long since fixed, but not everyone updates) bug in React Router’s Link component.
<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.Really the <a> tag should wrap the div, not the other way around.
It also avoids having large "white space" areas that are clickable, when only the text should be clickable. (Like when you wrap an <h1> with an <a> for example.)
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...
No, if you do the intuitive thing you get:
<a href="http://whereever/">foo</a>
which works fine for every user. a {
display: inline-block;
padding: 4px;
background: lightgray;
border: 2px outset lightgray;
text-decoration: none;
}
a:active {
border: 2px inset lightgray;
}Links go somewhere.
Don't cross the streams.
> 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.
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.
Not an excuse, but it can be frustrating.
Maybe that's an indication that unstyling a button is a really, really bad idea?
Each design iteration of that page keeps using buttons for links, links for buttons, links that look like plain text etc.
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?
Don't do that. Having the signup form be its own page is simpler and less cluttered, thus better for the user.
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).