14 ms·
When going somewhere does a thing: on links and buttons
- oldstrangers 4y agoI made a big button that does something by going somewhere. https://gloutir.com/ https://gloutir.com/
- cantSpellSober 4y ago`role=button` is not a replacement for <button> or <input> either!
- uup 4y agoWhy not?
- cantSpellSober 4y agoGreat question! The value of `role` tells the screen reader the element is a button, that's all. To be focusable, handle touch, mouse and keyboard (space and enter ofc) inputs you could write bespoke JS and CSS, or change `div` to `button`
- eyelidlessness 4y agoThis is all true and correct advice. I’m reticent to add this because, but for those curious about how close you can get to native <button>/<input type="button"> without the native form control, tabindex=0 gets you pretty much there. They’re all effectively useless without JS and all have the same styling capabilities these days, however, so better to just use the thing that’s designed to be a button unless you have a really special use case that you really understand (you don’t).
- Vinnl 4y agoThat doesn't quite get you there, though. For example, it doesn't submit a form it is contained in when clicked. There are some use cases where a <button> won't work (eg if you want to use flexbox), but even then I'd first re-evaluate how important that use case is, then reach for a properly tested library to turn another element effectively into a button [1], and only then try to implement it myself and probably forget some built-im functionality, breaking things for users and costing me lots of time. [1] https://react-spectrum.adobe.com/react-aria/useButton.html#custom-element-type https://react-spectrum.adobe.com/react-aria/useButton.html#c...
- eyelidlessness 4y ago> That doesn't quite get you there, though. For example, it doesn't submit a form it is contained in when clicked. Er sorry, I meant type="button" for both. Neither submit a form or do anything other than show the default interactive styles without JS. > There are some use cases where a <button> won't work (eg if you want to use flexbox) I’m not sure what you mean, and having a hard time imagining what you might mean. Can you elaborate?
- Vinnl 4y agoMy example was wrong, your sibling comment [1] provided a better one. [1] https://news.ycombinator.com/item?id=33173406 https://news.ycombinator.com/item?id=33173406
- runarberg 4y agoFlexbox not working in buttons is news to me (and I use display: flex and display: grid all the time). I just tested in both Chrome and Firefox and display: flex works just fine inside a button. I think there was a bug in Chrome a couple of years ago where they incorrectly denied some element the ability to be flex containers (<fieldset> was a really annoying case of this) but I think that is fixed now. The only case that I can think of where you can’t use a <button> is if you have nested interactive elements (a button within a link/button). There are sometimes ways around that (absolute positioning of the outer link/button) but sometimes there aren’t and then you need to re-implement a fake button from a <div>.
- rado 4y agoAnd supports "disabled" by default.
- etchalon 4y agoLink == new screen. Button == mutate existing screen.
- cantSpellSober 4y agoLinks can go to another location on the same screen, or a geolocation, email; any URL
- tartoran 4y agoSeemed to me links jump somewhere on the same or on a different page and buttons do stuff though the line is blurry, for example on a form submit a new page could render..
- brandrick 4y agoAre those two things always mutually exclusive?
- mandelbrotwurst 4y agoThe article states that they are not in the sentence immediately below the part where this quote was sourced.
- CodeSgt 4y agoThe article addresses that
- bob1029 4y agoIn my opinion, a link - as clickable by a user - should never be able to mutate the state of the system.
- nemothekid 4y agoIsn't the current browser path part of that state?
- bob1029 4y agoArguably, yes. What I was really trying to go for with "state" in this context was something more like "business state". Things on the server that you change and can see with a refresh on a different client.
- greysphere 4y agoGonna be a tough sell for verification emails.
- remram 4y agoWe can just agree that it should be a button and is only a link because of the limited HTML subset available in emails.
- Nextgrid 4y agoNot really - the link points to a page containing a button. You'd need to do this for practical reasons too, considering links in e-mails might get automatically fetched whether for malware scanning, caching or generating a link preview, and it would erroneously trigger your verification workflow.
- taneq 4y agoIf it’s a GET, it’s a link, if it’s a POST, it’s a button? :)
- paxys 4y agoThat's pretty much exactly how the web was designed – an anchor link is a GET request, a button is a POST. However, as the article points out, this analogy breaks down once you go beyond basic HTML and into complex UI layouts.
- hn_throwaway_99 4y agoI actually think the link solution in the Codepen box shows perfectly what's wrong with the link solution: Links should (and do by browser default) maintain their history state, while buttons do not. If you don't want to maintain the change in back button state, don't use a link. If in his link example I click the "Open Theme Controler" link, then click the "Close" link, and do that a couple times, when I then click the back button to come back to Hacker News, I'm instead cycled through the number of times I clicked those links. I doubt any user would expect that to happen.
- eyelidlessness 4y agoI was writing this corollary to the new tab rule of thumb, with the exact example of CodePen embeds, but backed out to see if someone else added it already. Drives me bonkers every time my browsing history gets polluted by storing local state in the URL. And now that I think of that phrasing, I think that probably the unifies the rules of thumb: if it changes local state, it’s a button. If it changes local scope, it’s a link.
- graftak 4y agoThat’s because they implemented the link using history.pushState (default non-js link behaviour) when history.replaceState should be used instead. It might still be valid to use a link for an on-page modal, for instance when it needs to be navigationable or should persist on a refresh.
- hn_throwaway_99 4y ago> (default non-js link behaviour) I mean, that's pretty much my whole point. Forget javascript (as the example in the article does), but links by default append to the state, because that is pretty much how browsers always worked before they even exposed the history API to javascript.
- Anon_troll 4y agoOne major problem here is the mixup of UX and technical implementation details. From UX point of view, the link example goes nowhere, it just opens a dialog. From that point of view it the fact it uses anchors to do so is not really relevant. From purely technical point of view, the question would be rather irrelevant as the distinction between a button and link is mostly how a human perceives it, it does not matter for the program. This is likely an explanation for the awkwardness that the author mentions feeling of this implementation, and is supported by it not making sense to open this kind of a "link" in a new tab (because it does not go anywhere).
- paulcole 4y ago
- paxys 4y agoCould we change the submission title please? The entire article is in fact debunking this point.
- aidenn0 4y agoIMO: If it makes sense to "open in new tab" then it should be a link. Otherwise it's a button. Corollary: If it's a link then middle-clicking on it better open it in a new tab! There are way too many times that this was broken by JS with the href just being set to "#" or something, but clicking the link, copying the new URL, opening a new tab, pasting the url, going back to the original page and hitting "back" did exactly what I wanted. Don't do this!
- quickthrower2 4y agoOr simply, if it is a form <button> make it look like a button. Otherwise if it is an <a> make it look like a link. Also related: if it is a GET request, don't mutate state or perform an action on the server (except perhaps logging). But that is basic security too. There are exceptions, but know why you are doing the exception. For example a landing page will typically have button-like links for call to actions, because people expect that.
- aidenn0 4y agoIf it's an <a> don't just make it look like a link, make it act like a link instead of having the href just be "#" and overriding what it does with an onclick().
- FridgeSeal 4y ago> If it makes sense to "open in new tab" then it should be a link. Otherwise it's a button. The problem is that apparently, an infuriating number of Front end devs seem to think that nothing in their shouldn’t-have-been-an-SPA page should ever be a link and go somewhere, preferring instead to waste an equivalent amount of time popping up some modal or changing page anyway.
- aidenn0 4y agoBut a lot of times they have a useful routing library (even if by accident) that updates the URL, so opening a new tab with the update URL actually does something useful, but it's not a link so I can't do that.
- alisonatwork 4y agoMy rule of thumb: if you could ever imagine a user wanting to control-click open in new tab or right-click open in new window, it should be a link. It's infuriating how many modern sites don't let you do this when the thing you're clicking on clearly ends up displaying a different view that you can independently navigate to in another tab or window.
- nostromo 4y agoSometimes command+click will still work to open into a new tab when a right-click does not.
- sio8ohPi 4y agoSometimes Command+Click will open in a new tab when Middle Click doesn't work, and sometimes Middle Click will open in a new tab when Command+Click won't work. If you're using Gmail, you get both types of behavior on the same page!
- Tagbert 4y agoIsn’t middle click a user defined function? Is it system defined? I assume you could assign ctrl/cmd-click to the middle button if you want. I’ve not worked on a system with a middle mouse button in many years.
- aidenn0 4y agoI haven't owned a mouse without the ability to middle click ever (my first mouse had a ball and 3 buttons; I think a Logitech c7?). If your mouse has a scroll-wheel, then it's probably clickable as a middle-click. If you have a trackpad without a 3rd button then there is usually a gesture that will send a middle click.
- aendruk 4y agoAnd some of those times, the parent still navigates so you get duplicate tabs. Ugh!
- dayeye2006 4y agoJust use <div> [doge]
- chiefalchemist 4y agoNot to get off-topic, but in the site footer the author mentions he's the developer of: https://polypane.app/ https://polypane.app/ Has anyone used it? Thoughts?
- wohfab 4y agoUsing it for quite a while now. It is amazing. Even 'just' using the multi device view is mostly enough for me, but it goes a lot further with accessibility audit functions and such. I definitely recommend trying it out.
- keithnz 4y agono, but I do use https://responsively.app/ https://responsively.app/
- davidbarker 4y agoThere's also Sizzy (https://sizzy.co https://sizzy.co). It's available standalone, but it's also included with a Setapp subscription (https://setapp.com https://setapp.com — Mac app subscription service).
- keithnz 4y agoyeah, sizzy is cool, it's what lead me to responsively as these monthly charges just don't match how I use the tools.
- rikschennink 4y agoI actively use it. I'm pretty familiar with responsive design so I'm honestly not using the multi-viewport size set up that much. But it can also show dark/bright view next to each other, set up viewports with different networks speeds, and toggle various media preferences which is just super handy as these settings aren't that easy to toggle in default dev tools. A nice extra is the page info pane which makes it super easy to validate all the metadata + check how the social cards show on popular networks.
- 4y ago
- pronlover723 4y agoFor example, Pronhub doesn't let you ctrl/cmd click images or links. You can right click and pick "open in new tab" tho
- kevin_thibedeau 4y agoMiddle click works. It's a shame that input devices have devolved for the sake of style and fashion.
- stjohnswarts 4y agoyeah middle click is underutilized by most netizens. One click to open and close them all and in the darkness bind them.
- BeFlatXIII 4y agoThankfully, there are browser add-one to restore right-click functionality.
- BlueNorth 4y agoPersonally, I use a <input type="checkbox"> to do that kind of thing, like the hamburger menu.
- eyelidlessness 4y agoI do this too if I’m trying to play JS payload golf and the stakes are low for users, but I always feel guilty because I know it harms accessibility. JS is actually required to make an expandable/collapsible menu accessible, even if your clever pure-CSS solution seems bulletproof. It’s a shame, there really should be native controls for this kind of thing that don’t require arbitrary executable code.
- deleted 4y ago[deleted]
- runarberg 4y agoThis is precisely what <details> <summary> is for. No javascript required. It gives the correct semantics for assistive technology, correct interactions with the keyboard, focusability, etc. I recommend you use it over the old checkbox hacks or javascripts.
- jameshart 4y agoYes! This example is a control that toggles the visibility of part of the page. It is neither a link nor a button And, you know, if you think about this from an assistive technology point of view, does a screenreader user actually need to worry about interacting with a control to make something visible? Isn't it better from their point of view to skip the interaction entirely and just put the list of theme options semantically under a navigable page heading?
- tempestn 4y agoIn this specific example, is the visual theme of the page even relevant to a screenreader user at all?
- 4y ago
- andirk 4y agoDefault computer peripheral behaviors to please not mess with: - right-clicking defaults - scrolling defaults - Back/forward browser buttons to traverse _state_ as the user expects - tabbing (and leave the damn default outline!) If it's not a video game, please don't F with my keyboard and mouse's default behaviors. Thank you.
- Nextgrid 4y agoDon't fuck with Cmd+F (or whatever the Windows/Linux equivalent of that is) either. If I press Cmd+F, I want the proven, fast, local, browser-based search with the consistent UI I'm used to. Not some shitty Javascript replica whose functionality I can't predict and in practice ends up disappointing.
- sholladay 4y agoI respect this distinction in almost all cases. However, login and signup feel like they deserve to be styled as buttons, perhaps because they are the first step of a flow that will eventually have side-effects. However, they are just links on the home page.
- mmis1000 4y agoI think it must be a link if you would expect user want to open in a new tab, no matter it pushes history (navigation) or replaces history (in page tab). There are countless of times that middle click to open new tab didn't work because page author use <button onclick="location.href='xxx'> as link. It's such an awful experience.
- jameshart 4y agoThe thing that bothers me about this whole insistence that, for accessibility purposes, it is vitally important that we correctly employ links and buttons to ensure that users of assistive technologies can correctly anticipate whether an interaction will go somewhere or do something... Why do only assistive technology users get treated with that level of respect? Because let's be clear - for sighted users interacting with this person's webpage, whether the markup is a link or a button, they evidently plan that visually it's just going to be a paint roller icon, inside an area of the screen of indeterminate size which is going to be somehow interactable. Apparently it's not important to consider whether I, a user not currently employing assistive tech, might need to know before I click it whether that control will cause a page navigation, carry out an operation, or what. It might be a link; it might be a button; it might just be a decorative picture of a paint roller. It might interact on hover, on click, or on double click. Who knows! This definition of accessibility as something distinct from usability, where frontend devs will torture themselves over the semantic markup that they use to ensure clarity of purpose for accessibility purposes, has somehow become completely divorced from the world of UX design, where visual indications of affordances are no longer seen as valuable.
- Timwi 4y agoOnce upon a time, links had an underline and buttons had a beveled frame. We seen to have somehow come to accept the visual designers’ claim that, for some reason, we can't do that anymore.
- laundermaf 4y agoSo when do I use `<div onclick>`? /s It’s disappointing how developers are so lazy to not even know the basic concept of a link. It’s completely ridiculous yet super common to see click handlers on DIV elements that set the value of location.href As for A/BUTTON, we really need an attribute that clears the button’s style entirely, safely and forever. Nobody knows how to properly and full drop all useragent styles from a button, try googling it.
- Gigachad 4y agoThis comes from the fact that SPA routers work best when you use JS to update so you don't have the page flash like a normal page load. React router at least has a trick element which is an a tag with href but if you click it, it intercepts it an does an onclick load. But it still works as a link for all other purposes like copying location.
- wildrhythms 4y agoI keep wondering if this can be attributed to front-end devs learning SPA libraries (React, Angular, etc..), skipping the 'boring boilerplate' by attending boot camps that start them with a gigantic node_modules/ folder, and never actually learning the fundamentals of HTML, like anchor links (I doubt such developers even know that the 'a' tag stands for 'anchor'). So we end up with unsemantic div soup everywhere, and such developers breaking into a cold sweat when someone utters 'accessibility' in proximity to their demo.
- yawnxyz 4y agoSometimes it does both — e.g. when I use Front and click on an email, it does something. But I should ALSO be able to open it up in a separate frame, for long readings (in Front you do this by double clicking). Is it good practice to use links, then intercept then with preventDefault when it should go somewhere AND do something?
- bobmaxup 4y agoForm submissions should be links?
- runarberg 4y agoThis button should have been a <details> <summary>. And this rule of thumb is also incorrect (albeit by technicality). A form submit button goes somewhere (to the action response) and is a button. I agree with the sentiment though, in general: - If you are navigating through the page, use a link, - if you are performing an action, use a button, (and in addition) - if you are reveling some information, use a <details> <summary>
- kortex 4y agoI just learned about using this tag in github comments for hiding full tracebacks or large code blocks and it is such a usability game changer.
- chrismorgan 4y agoOf straight HTML, <details> is certainly the most appropriate semantically (and it’s what I use on my site). This particular site would find it mildly difficult to apply since the picker body affects layout but is in a different part of the document to the button, but since its height is known it could just barely be done. Another semantically-reasonable possibility which allows separation of source and destination would be using a button with appropriate aria-controls and aria-expanded to link it to the picker body; and probably giving that body the dialog role.
- runarberg 4y agoYeah I agree. I probably would have used a non-modal dialog here. You can actually absolutely position (or, rather sticky positioned) the body of the <details> to the top. But I think the dismiss button, inside the dialog warrants it being a <dialog>. Dialogs usually open with a <button> (so that answers that question), and you would open this by calling dialog.show()—as opposed to the usual dialog.showModal()—since you don’t want to capture the focus. The Benefit of using the <dialog> element is that you can put it anywhere you want inside your DOM structure and allow it to interact with the page however you want to.
- kilian 4y agoThere are multiple reasons why details/summary are bad semantics, outlined in this article: https://adrianroselli.com/2019/04/details-summary-are-not-insert-control-here.html https://adrianroselli.com/2019/04/details-summary-are-not-in...
- bkuehl 4y agoI used to be more adamant that links should never open modals and should be buttons. Until we ran into an action column in a grid having 4-5 items. Having it be all buttons would look ridiculous and annoy users with space usage. We went with link tags (some are true links and some are modals). Not a peep from users.
- 1vuio0pswjnm7 4y agoDare I ask, in the title, what is meant by the word "it". The word is used four times. However the meaning does not seem consistent across each usage.
- Existenceblinks 4y agoWCAG is kinda subpar. Last time I reached out definition of "owned" element and found there are open issues still discussing about it. In application context, I wonder if desktop apps are really accessible and no one complains about, or just the web got really bad rep partly because they are more accessible..bad examples.
- penguin_booze 4y agoA stock broker once tricked me into to executing a trade when I visited a link they sent on email--no validation; no login; no confirmation beforehand. I visited the "unique URL", and that was it.
- laundermaf 4y agoKinda unrelated. This is more of an issue with that brokering site triggering an action on a GET visit, not related to HTML
- DitheringIdiot 4y agoI’ve written a tutorial on building one of these that uses a checkbox. There’s more ways than a button or a link. Some people have suggested in the comments using details and summary. It works without javascript, represents the states open and closed without requiring any aria attributes and some other usability features people might find interesting. https://endtimes.dev/html-and-css-only-multiple-color-scheme-picker/ https://endtimes.dev/html-and-css-only-multiple-color-scheme...
- datagram 4y agoGitHub uses <details> for most of their dropdowns and it does generally work well, though you'll run into issues if you ever need to break out of the DOM hierarchy (for example, to have the popup overflow a scrollable container).
- michaelsalim 4y agoJust make everything a link (a tag) unless you can't. Doesn't matter how it looks like. It can be some text with underline or it could look like a button. Even if the button only does some action on the page, it could still be represented with a url. Sometimes it doesn't make sense. Then that's the time to use something other than an a tag. If this were the default, most of this problem wouldn't exist.
- simon_sinister 4y agoSquare.com uses similar looking links and buttons in a dark pattern to trick users. Login and land on the Home page. You want to look at transfers to your bank account (Balance > Account). Here you see big blue link box taking your to Balance: https://postimg.cc/yD97T8yT https://postimg.cc/yD97T8yT Sometimes this blue box is a button to initiate an early transfer, which triggers an additional early transfer fee: https://postimg.cc/t1jpvGrG https://postimg.cc/t1jpvGrG Once you get to the Balance page, you still need to find the link taking you to the Account page (View All Transfers) to actually see your transfers. Square takes a second stab at getting that fee with a big blue button in the middle of the page: https://postimg.cc/bG98KVMD https://postimg.cc/bG98KVMD Now perform this same action several times a week, all year round, and you will make the mistake and press the transfer button. It only takes once for you to have a never ending enmity towards Square for filching $25 from your income. I was caught the once in October of 2021. I *recall* the transfer was initiated immediately (and the extra fee of 1.5%). Since then I've revisited the button when the transfer was low, and I was willing to risk $5 to get a screen shot of the next page. That time I did find a confirmation screen (I can't find the screen shot now). I call support, but they would not refund the transfer, despite having pressed it by accident, despite having never used the feature before, and having over five year relationship with about 200k/yr in sales going through their platform. "But you're getting the service" was their reply.