[HN Gopher] Just use a button
___________________________________________________________________
Just use a button
Author : moebrowne
Score : 212 points
Date : 2025-10-31 16:59 UTC (6 hours ago)
(HTM) web link (gomakethings.com)
(TXT) w3m dump (gomakethings.com)
| giancarlostoro wrote:
| Weird, I always use buttons when I can, unless what I need is not
| actually a button, but something that performs and on-click sort
| of like a button, like a hyperlink that navigates you through the
| web app.
| ervine wrote:
| I guess if it doesn't update the url, it's a button.
|
| If it changes the url, it should be a link. At least that's how
| I've always done it.
| cassepipe wrote:
| Is is not okay to wrap a link inside a button ? I guess not
|
| Which elements are allowed to wrap which is unclear to me
| stevula wrote:
| What is the use case? It's hard for me to think of a reason
| you'd want to wrap a link in a button. If you want to
| navigate, use an anchor. If you want to trigger JS logic,
| use a button with onclick handler. If you want to navigate
| while doing some side effect like an API call, use an
| anchor with onclick handler (and don't prevent default).
| cferdinandi wrote:
| Literally absolutely never ever do this.
| Shog9 wrote:
| FWIW, you can generally figure out what's allowed fairly
| quickly by checking the content model for a given
| element[1]. Some browsers might be more or less
| restrictive, but for normal usage this'll be more than
| enough to avoid unexpected behavior.
|
| [1]: https://html.spec.whatwg.org/#the-button-
| element:concept-ele...
| Zak wrote:
| > _like a hyperlink that navigates you through the web app_
|
| You mean an <a> tag?
| bugsliker wrote:
| - tabindex=0 doesn't affect ordering, does it?
|
| - why do you need to listen for events at the document level?
|
| not that i disagree with the article, but some arguments didn't
| seem right.
| thyristan wrote:
| > - tabindex=0 doesn't affect ordering, does it?
|
| Of course it does. tabindex=0 doesn't sort naturally into the
| automatic tabindex order, it sorts AFTER everything. So you are
| jumping through all the other tabindex elements, then you are
| jumping back to all tabindex=0.
| brandonhorst wrote:
| This is incorrect. https://developer.mozilla.org/en-
| US/docs/Web/HTML/Reference/...
| thyristan wrote:
| That is correct. From your link: "tabindex="0" means that
| the element should be focusable in sequential keyboard
| navigation, after any positive tabindex values. The focus
| navigation order of these elements is defined by their
| order in the document source. "
| Ma8ee wrote:
| Your link actually supports the comment you replied to.
| pverheggen wrote:
| That's the same behavior as a <button> without tabindex, like
| the author is proposing.
|
| It's generally advised not to set tabindex to anything but 0
| or -1 and let the document order dictate tab order.
| thyristan wrote:
| > That's the same behavior as a <button> without tabindex,
| like the author is proposing.
|
| Yes, but often you have elements with taborder > 0.
|
| > It's generally advised not to set tabindex to anything
| but 0 or -1 and let the document order dictate tab order.
|
| Only if document order is sane. Usually with modern
| websites it isn't, document order is a broken notion if you
| can position elements at will and e.g. put navigation at
| the bottom of a document but move it to the top by CSS.
| Which is actually a recommendation that some people make
| for acessibility...
|
| What you usually want to do is assign a sensible taborder >
| 0 to the one form element that the user is probably
| currently using. Otherwise, he will pointlessly tab through
| search, menus, cookie bars and a ton of other pointless
| stuff first.
| pverheggen wrote:
| > Yes, but often you have elements with taborder > 0.
|
| You can just as easily apply the same tabindex to a div
| though.
|
| > Only if document order is sane. Usually with modern
| websites it isn't...
|
| Well that's the real problem, all your non-interactive
| content (like text) is going to be out of order too.
| You're just adding to the confusion if buttons and other
| inputs are in a different order from the content they're
| associated with.
|
| > Otherwise, he will pointlessly tab through search,
| menus, cookie bars and a ton of other pointless stuff
| first.
|
| The proper way of dealing with this is a "Skip to Main
| Content" element:
|
| https://webaim.org/techniques/skipnav/
| thyristan wrote:
| > The proper way of dealing with this is a "Skip to Main
| Content" element: > >
| https://webaim.org/techniques/skipnav/
|
| No, it isn't the proper way. That only works if you can
| see the skip link and know to press enter. Otherwise you
| will tab straight into the navigation. So possibly useful
| for screen readers, but completely useless for most
| keyboard users. Yet another stupid webdev workaround for
| a selfimposed problem.
|
| What you should do is autofocus the first form element
| (if there is a form), give it tabindex=1 and number the
| other form elements in a sensible ascending tabindex
| order. Otherwise, proper semantic markup is sufficient,
| even for screen readers.
| pverheggen wrote:
| Usually you would have it appear when it's focused, like
| this for example:
|
| https://www.nytimes.com/
|
| And yes, this is an acceptable solution according to the
| W3C:
|
| https://www.w3.org/WAI/WCAG21/Techniques/general/G1
|
| Your solution of focusing the first form element is
| pretty idiosyncratic. It's better to follow WAI patterns,
| because patterns have predictable behavior. Otherwise,
| keyboard users will have to learn how to interact with
| your website from scratch, instead of just following the
| same pattern they're used to from other sites.
| thyristan wrote:
| Any website implementing a form for data entry is
| expected by any sane user to autofocus the first form
| element.
| pverheggen wrote:
| Sorry, missed the part about "form for data entry". If
| that's the main point of the given page, then sure, focus
| on the first input is fine.
|
| Your original comment was to use tabindex to skip search,
| menu bars, breadcrumbs, etc. and for that there are
| better options.
| MrJohz wrote:
| I would be very surprised if a website autofocused almost
| anything on page load, except for very specific
| applications where that makes sense. I just tried
| clicking through some forms on gov.uk, which is a website
| that has spent a _lot_ of time testing and improving the
| UX of their forms, and none of them had autofocused
| elements, not even on later pages after having already
| filled in elements.
|
| I can imagine screen readers would deal particularly
| poorly with this behaviour, because the user would be
| dropped in a field without any of the context of the
| page, just the field label to work with. However, I've
| not been able to test that out properly.
|
| I don't think the behaviour you're describing is anywhere
| near as common as you think it is, and I suspect it would
| make a page less accessible for a number of kinds of
| users.
| MrJohz wrote:
| You almost certainly don't want to assign tab order
| manually. Theoretically, if your html is out-of-order for
| some reason, then you can fix it with taborder, but there
| are so many issues with out-of-order html that it's much
| better to avoid that in the first place. Even on modern
| websites, it is almost always easier to lay your html out
| in the correct order rather than messing around with the
| order via CSS. (I read an article recently by a web
| accessibility expert that discussed the issue of
| flexbox's order parameter and how the working group
| designing it failed to accessibility into account when
| adding it to the spec:
| https://alice.boxhall.au/articles/a-threat-model-for-
| accessi...)
|
| You mention using it to skip a nav header or something
| similar, but (1) you have autofocus for that if you need
| it (and you don't usually need it), and (2) the pattern
| where you provide a "jump to content" button is typically
| a better approach, because it allows the user to decide
| what they want to do when they arrive on your site,
| rather than you deciding for them. If the "jump to
| content" button behind visible when focused and is the
| first element on the screen, then it works perfectly for
| screen readers and other keyboard users, and you don't
| need to handle taborder manually.
|
| There are always exceptions to these sorts of rules, and
| some times tabindex might be necessary, but I've not yet
| come across a case where the problem couldn't be solved
| better in a different way.
| bugsliker wrote:
| I'm saying tabindex=0 is naturally sorted wrt other naturally
| focusable elements. That matches the behavior of the <button>
| you're trying to emulate. I don't know what tabindex>0 has to
| do with this.
|
| See this fiddle https://jsfiddle.net/483uqjnp/
|
| (again, I do not condone building your own <button>, just
| pointing this out)
| minitech wrote:
| tabindex=0 _does_ sort naturally into the automatic tabindex
| order.
|
| > So you are jumping through all the other tabindex elements
|
| This part is correct (for elements with an explicit positive
| tabindex), which is why specifying an explicit positive
| tabindex is considered a code smell. If you don't specify a
| tabindex on an element that's focusable by default, it
| behaves like tabindex=0.
|
| Try it: data:text/html,<button>foo</button><i
| tabindex=0>bar</i><button>baz</button>
| cferdinandi wrote:
| Hey, it's me, the original author!
|
| The issue isn't with tabindex=0 specifically, but fucking with
| tabindex in general. People go down that path, and start
| putting that shit on everything, like it's Frank's Red Hot.
|
| And in my experience, the same folks who use div's instead of
| button's are the ones who don't know better and start throwing
| tabindex around.
|
| "why do you need to listen for events at the document level?"
|
| Not events generally, keydown events specifically, which do not
| fire on child elements of the document.
| pverheggen wrote:
| Not sure about that, MDN's example shows keydown being
| attached to an element.
|
| https://developer.mozilla.org/en-
| US/docs/Web/API/Element/key...
| susam wrote:
| > Not events generally, keydown events specifically, which do
| not fire on child elements of the document.
|
| Are you sure? I have a 17 year old HTML tool written using
| plain, vanilla JavaScript where keydown on a child element
| seems to have been working as expected.
|
| https://susam.net/quickqwerty.html
|
| https://github.com/susam/quickqwerty/blob/1.2.0/quickqwerty..
| ..
|
| Nice article, by the way!
| skrebbel wrote:
| I think that's because it's an input and not a div, so it
| can get focus. Im not sure whether tabindex is enough to
| make a div do that too, article suggests no
| kyle-rb wrote:
| Hi, good premise overall, but there are just a lot of little
| things that are off.
|
| - It only counts as "fucking with tabindex" if you give it a
| value that's not 0 or -1. You should give that specific
| disclaimer, because there are uses for tabindex=0 other than
| reimplementing <button>.
|
| - Divs can definitely receive keydown events. If I go to an
| arbitrary web page, pick a div and run `div.tabIndex = 0;` +
| `div.addEventListener('keydown', console.log);`, I see those
| events coming through when I have the div keyboard-focused.
|
| - "Run your code, somehow..." I think just calling
| `notRealBtn.click()` is the best option.
|
| - Stupid but semi-interesting nitpick: 'keydown' is good for
| enter, but you should be listening to 'keyup' for the space
| bar. That's how real <button>s work anyway.
|
| - The 'keyup' listener should call event.preventDefault() to
| prevent the default behavior of the space bar scrolling the
| page.
| tarwich wrote:
| 100%
|
| Use elements as close to their original intention as possible
| flemhans wrote:
| Why is the <div> option proposed by anyone in the first place?
| wrs wrote:
| Based on what I see in the world, I suspect one reason is that
| a <div> makes it easier to apply some bizarro appearance to the
| button, so it not only doesn't act like a button, it doesn't
| even _look_ like a button.
| mcny wrote:
| This comes from either business or the UX people who want
| stuff to look pixel perfect to their stupid wireframe.
|
| Why does a website that sells to a pretty much captive
| audience who cares more about functionality than looks obsess
| so much about every single button looking pixel perfect to
| some arbitrary wireframe, I will never know.
| Joker_vD wrote:
| Well, have you been on, I don't know, TV Tropes? They have
| those long lists, that are separated into "folders" on a single
| page. You can click on those "folders" to expand/collapse them,
| and it's implemented as a <div> with "onclick" property and
| <ul> inside it (well, used to IIRC; nowadays this <ul> is a
| child of a sibling <div>).
| 1-more wrote:
| what's annoying about that example is that all of those
| <div>s could be buttons with no other changes. The only
| content inside the button <div> is the title and folder icon,
| not the list of examples associated with that title. That's
| just fine for a button!
|
| The other thing I'd do is add `aria-controls=folder0` to the
| button that toggles visibility of the list with `id=folder0`
| no_wizard wrote:
| I'll do you one better and argue they could `<details>`
| elements. This is a perfect use case for that.
| 1-more wrote:
| I use them EXTENSIVELY but some don't like them for being
| annoying to control en-masse with the "toggle all
| folders" button at the top. But yeah I 100% agree with
| you. I've snuck them into a webapp where I just needed
| that much local state rather than have the whole page's
| state care about the collapse/open state of that one
| thing.
| cferdinandi wrote:
| The most common reason I've seen is whining about having to
| override default button styles.
| no_wizard wrote:
| I too have encountered this reasoning.
|
| Then I write some basic CSS and show them they have nothing
| to fear.
|
| Yet, I still remain irritated beyond belief that its such a
| common thing. In 2025. Hell, in 2017!
|
| I don't know what to do about it, other than constantly
| remind people about things, but it gets tiring.
|
| Though, its a great interview question. Its a quick way to
| understand if someone knows the fundamentals or not.
|
| Kinda like how people got ".bind" wrong on functions for
| years.
| 827a wrote:
| > This element does not announce itself as an interactive element
| to screen reader users.
|
| Is this actually true nowadays? Given that advice like this is
| often parrotted by people who don't actually use screen-reading
| software, I sometimes wonder if this is a situation where we've
| just been saying this and repeating this advice; meanwhile,
| screen readers have _obviously_ become sophisticated enough to
| recognize that a div with an onclick handler on it is probably,
| you know, clickable and interactive.
| mnhnthrow34 wrote:
| Have you tested this? Often click handlers are on some non-
| interactive ancestor element, it is not a good heuristic for
| something being interactive itself or what name it should have.
| Sometimes the listener is on the body element and we just parse
| out the triggering element and do something.
| 827a wrote:
| No I haven't tested it, that's what I'm asking.
|
| This piece of advice, to me, just feels like a piece of
| advice constantly repeated by a bunch of people, none of whom
| actually use the software for which the piece of advice is
| meant to benefit. That scares me; like we've all lost touch
| with the ground truth on this one; I'd love to re-sync with
| it, that's what I'm trying to do, I just don't have the first
| clue how to do it.
| SoftTalker wrote:
| Screen reading software seems like it would have a very small
| market and I would expect it lags rather than keeps up with the
| ever changing ways people invent to build web pages.
| isleyaardvark wrote:
| Screen readers have and continue to lag in implementing
| standards designed specifically for accessibility, so I would
| say they are obviously not sophisticated enough.
|
| (One example: https://heydonworks.com/article/aria-controls-is-
| poop)
| pverheggen wrote:
| There are well-defined standards for how the role of every
| element is determined, and according to those standards, adding
| an onclick handler does not change the role.
|
| Screen readers also don't access the DOM directly, there's an
| extra abstraction layer. Browsers expose accessibility data to
| the appropriate OS API, and screen readers use the data exposed
| by the OS. There's too much variation as-is between different
| screen readers to be piling browser-specific behavior on top.
| Joker_vD wrote:
| > 1. This element does not announce itself as an interactive
| element to screen reader users.
|
| It has the "onclick" property set though. The other two points
| are pretty valid, however. It's a shame we don't have a proper
| "onsubmit" property or something like that. "Oninteract"?
| pverheggen wrote:
| A good addition to this article is that most buttons should have
| type="button" on them. By default, buttons are type="submit",
| which if contained inside a form will submit that form.
|
| I'm sure there are some devs who reach for a div because they're
| unaware of the proper way to disable submit behavior.
| rado wrote:
| Right. I learned it the hard way lol
| galaxyLogic wrote:
| > they're unaware of the proper way to disable submit behavior.
|
| That is an issue in favor of DIV, you don't accidentally set
| type="submit" because you don't know about that. There are many
| things many people don't know.
|
| Using a DIV means you start from empty plate and explicitly add
| the features you want to add, which makes it easy to later
| remove or change those features when you want to.
|
| Of course if your knowledge of HTML standards is great and
| Button exactly fits your current use-case you probably will use
| it, but designs and requirements change all the time.
|
| Using DIV makes your design more transparent, you see there are
| certain features you have set to it by adding the attributes.
|
| Using a Button means you (and other people reading your code)
| probably want to consult documentation to understand what it
| exactly does. With a DIV + attributes that is explicitly
| "spelled out".
|
| Just some pros and cons.
| thyristan wrote:
| DIV isn't a button with features disabled. DIV is something
| else entirely, and you have to emulate most of the features
| in Javascript, badly. As the original article explains...
| marcosdumay wrote:
| Every input should have a type. It's a good thing to put in a
| linter and run before you consider your code complete.
|
| Yes, the default is bad, but you should be overriding every
| one of those anyway.
| MrJohz wrote:
| You always want all the accessibility features. If your
| button is a button, then you want the whole lot: the correct
| role, tabability, keyboards shortcuts, everything. There is
| no situation where you only want some of those features.
|
| So if you use a div, you _always_ need to add _all_ of the
| features. Whereas if you use a button, you usually need to
| remember to add the correct "type" attribute (although if
| you're building a form, you might not even need that).
|
| You also mention transparency. A button makes your design
| transparent: it is a standard element, and web developers
| should know what it does. A div is not transparent - firstly,
| if I'm a developer reading that code, I need to look at
| context clues to understand what the authors' intent was (a
| tabbable element with a keydown handler and a click handler
| could be all sorts of elements, not just a button, so now I
| need to inspect event handlers and see what they do), and
| secondly, many people do not implement this stuff correctly,
| so what you're usually looking at is something that looks
| like it might have been intended as a button, but is missing
| a bunch of features. Was that intentional or did the author
| just forget some stuff?
|
| This isn't really a "pros and cons" type of thing. Just use a
| button. It's doing all the work that you'd have to do
| manually, but automatically. Just use it.
| znort_ wrote:
| > Of course if your knowledge of HTML standards is great and
| Button exactly fits your current use-case you probably will
| use it
|
| i would have imagined that coding html should be done by
| people with basic understanding of it, at the bare minumum to
| know what a button is. but maybe that's just me being old and
| not going on with the vibes ... maybe i'm just going to
| facepalm a bit and get some fresh air.
| jmull wrote:
| How is it harder to learn "want normal button" => <button
| type="button"...> than "want normal button" => <div
| role="button" tabindex="0"...>, plus the javascript for
| keyboard access (plus css for at least the cursor), etc.?
| culi wrote:
| Agreed. It's not hard and it's definitely not unreasonable
| to expect front-end developers to know the very basics of
| semantic HTML and accessibility standards. It's literally
| their jobs
| Sohcahtoa82 wrote:
| > Using a DIV means you start from empty plate
|
| When comparing to a Button, that's a bug, not a feature.
| cferdinandi wrote:
| No. Objectively no.
|
| It is INFINITELY easier to add type="button" than all of the
| other shit I mentioned in my article.
| serial_dev wrote:
| So some developers cannot be trusted to figure out that they,
| in some cases, need to add a single attribute to the button,
| but they can reimplement a button with all its behavior,
| feel, look, and accessibility settings starting with a div?
| brazukadev wrote:
| React in a nutshell
| Levitz wrote:
| No, but they can reimplement it in a good enough state for
| the vast majority of users without getting bothered by
| default behaviour or styling that might vary per browser.
|
| Which, don't get me wrong, is still a problem,
| accessibility matters, but if there's a reason as to why
| something happens, the way to fix it is to actually look at
| that reason.
| Mawr wrote:
| > Using a DIV means you start from empty plate and explicitly
| add the features you want to add,
|
| Yep, which guarantees you will not add everything that's
| required for e.g. accessibility. It's not realistic for every
| single dev to be aware of every single important property of
| a button. This approach just doesn't scale.
| mixmastamyk wrote:
| Believe that default is for <input type="submit">, not
| <button>.
| pverheggen wrote:
| Nope, it's the default:
|
| https://developer.mozilla.org/en-
| US/docs/Web/HTML/Reference/...
|
| Maybe you're thinking of <input type="button">, which doesn't
| submit?
| cferdinandi wrote:
| It's the default for buttons inside forms, but it's SO
| trivial to add type="button" than any argument that div's are
| a better choice because of this should be dismissed as
| unserious trolling out-of-hand.
| tomkarho wrote:
| I seem to recall that once upon a time the default type for a
| button was in fact "button" but at some point (somewhere in
| the region of html 5 / es6) it was switched into "submit".
| sam_lowry_ wrote:
| Indeed this long rant by OP misses the critical info.
|
| A button of default type will do weird things, IIRC it will
| skip the JS handler onCick, for instance.
| efilife wrote:
| I don't think it skips the handler behavior on default but
| can't check now
| Shog9 wrote:
| It does not. What it _does_ do is submit the form, so if
| you trigger some fast change to the page or async behavior
| from the click event, you may never see it because the
| submission happens and the page reloads (or a different
| page loads if form action is set to a different URL). If
| you 're relying on event bubbling, the click handler may
| run _after_ the form is submitted, which is even less
| likely to do what you intend.
|
| If you aren't expecting this (and don't know how to
| discover it e.g. by examining browser dev tools, server
| logs, etc.) then you'll assume the button is broken and...
| probably try something else.
|
| Even if you _do_ discover it, you may try something that
| won 't quite have the same reliability - at one point it
| was common to see folks putting preventDefault() or return
| false in their click handlers to squelch the (correct)
| behavior, rather than changing the type of button.
| sam_lowry_ wrote:
| Yes, you are right. Thanks for the lengthy explanation.
| lyricaljoke wrote:
| My very similar pet peeve is about websites that use `onclick`
| handlers and similar to implement navigation. Just use a damn
| anchor tag, which gets you correct link behavior for free:
|
| * works with middle click for new tab
|
| * integrates with accessibility devices
|
| * works with right click + open in new window or similar options
|
| * etc. etc. etc.
|
| If it's notionally navigation, don't use javascript soup: use a
| link.
| Zak wrote:
| I've seen an increase in people doing this sort of thing over
| the past few years. I imagine it has something to do with
| frameworks and ignorance or apathy, but the old fashioned way
| almost always provides the best UX.
|
| To anyone reading who has tried to get fancy with a substitute
| for the <a> tag, I wish you mild discomfort and inconvenience.
| philistine wrote:
| Could it be that the devs who write that code are not allowed
| to touch the CSS so they implement the visual functionality
| they want in their framework instead of telling the design
| team their intent?
| Zak wrote:
| There could be any number of weird constraints that would
| lead a developer who knows better to do such a thing in a
| specific situation, but someone designed (or failed to
| intentionally design) the system in question.
|
| That person should sit alone in a room with no distractions
| and think about what they did.
| weaksauce wrote:
| when i was doing .net programming way back in the day asp.net
| handled each navigation with a javascript event and it broke
| all that stuff. this was right before ruby on rails existed so
| maybe it's better now.
| tln wrote:
| Yes! If it's clickable, it should either be a button or a link.
| culi wrote:
| there are plenty of other vanilla html elements that are
| clickable. <details>, <input
| type=[button|checkbox|radio|file|etc]>, <label>, <select>,
| etc
| epidemian wrote:
| oh, 100% yes! The job project i joined somewhat recently is a
| moderately-complex React web app, and _none_ of the navigation
| elements are actual links. Everything is done by onClick
| handling, even thought many things are, conceptually, just
| links. I have no idea why this kind of thing is so widespread
| on the web front-end world.
| derefr wrote:
| I wonder why browsers don't intercept JS-triggered navigation
| (or history.push) events that happen with a click handler on
| the stack -- where it can be determined from the event data of
| that click handler that the user additionally used the middle
| mouse button or was holding cmd/ctrl at the time -- and rewrite
| them into navigation-in-new-tab. (Ideally, without making the
| caller aware that anything different happened than what it was
| expecting.)
|
| It might not be what the developer of the site/app intended;
| but it's exactly the semantics the user is _expressing their
| desire_ to trigger. So why not do what the user wants? Browsers
| are user agents, not developer agents, after all.
|
| (Before you say "that sounds like a layering violation" --
| well, yes it is, but that particular layering violation already
| exists to support most browsers' JS engines' "suppress popup-
| window / new-tab navigation if the stack of the navigating call
| _doesn 't_ contain a click event" logic. The code ugliness was
| already bought and paid for; we may as well reap as much
| benefit from it as we can!)
| yakshaving_jgt wrote:
| > it's exactly the semantics the user is expressing their
| desire to trigger.
|
| That's not necessarily true. You could imagine writing
| perhaps a video game or something where this control is
| intended to have a different meaning. For this reason, I
| don't think this is a liberty that browser developers can
| take.
| derefr wrote:
| Keep in mind that this check+logic would only come into
| play _within_ the call to `history.push` or the
| `window.location.href` setter.
|
| It's not "add a browser-default click event listener that
| shims in special behavior" (which wouldn't be able to catch
| the JS navigation in the first place, since that would be
| occurring in its _own, separate_ click event listener.)
|
| It's instead "when I-the-browser have been called by page
| JS to do something navigation-like through the native
| `location` or `history` APIs, first check if the current
| call stack has a event-listener call triggered by a
| browser-delivered click event in its ancestry. If it does,
| check further whether the click was a "special" [middle-
| mouse-button / shift / ctrl-or-cmd / alt] click. If it was,
| then cause some other side-effect depending on the
| "special" modifier [i.e. open the target URL in a new tab,
| or new window, or download it] while silently failing to
| actually navigate _this_ tab. Otherwise, proceed with the
| original semantics of the native `location` / `history`
| API call that was made."
|
| If your game isn't specifically trying to have middle-
| clicking / ctrl/cmd-clicking _navigate the tab_ , then this
| check+logic would never fire.
|
| ---
|
| That being said, _in theory_ , if you bound a listener to
| `auxclick` and told it to `e.preventDefault()`, that should
| maybe tell the browser you're doing something special and
| different where the middle-mouse button isn't just "the
| left mouse button with extra flags set", and therefore that
| navigation triggered via the middle mouse button shouldn't
| be seen as "navigation triggered via the left mouse button
| with extra flags set."
|
| I say _in theory_ because web developers would probably use
| that to prevent people from opening their site /app in
| multiple tabs at once. And the whole point here is that
| people should be able to do this whether web developers
| like it or not.
|
| --
|
| Also, a tangent:
|
| Web developers may have what are, to them, _good reasons_
| for preventing the user from opening their page /app in
| multiple tabs.
|
| For instance, each instance of a page/app on their site
| might open its own persistent websocket connection to their
| backend, and so having O(N) tabs open to their site means
| O(N) websocket connections. And if many users do that,
| their backend falls over.
|
| Or each instance of the page/app thinks it has exclusive
| ownership of a local IndexedDB, and so might try to migrate
| the data in a non-atomic way at any time; where if other
| instances of the page/app are also running and accessing
| the same DB, they might blow up, or do the same thing and
| corrupt the DB.
|
| (I've seen both of these in practice. In fact, I believe
| _Reddit_ [in its new design] does the former; at around
| ~100 open Reddit tabs, they all crash! [I think it has
| something to do with their chat system.])
|
| IMHO, any webpage that can't stand being open multiple
| times simultaneously is badly architected. Such pages have
| been "coddled" too long by browser vendors, by allowing
| devs to _mostly_ disable the user 's ability to easily open
| links as tabs. We should stop coddling these pages.
|
| If we give users back the ability to easily open tabs on
| modern websites, we'll see the owners of these sites
| finally [probably begrudgingly] fix the problems that cause
| them to want to disable opening things in tabs in the first
| place.
| psygn89 wrote:
| Yup. I think a lot of the devs that started with React jumped
| straight into the "fun" stuff without learning some of the
| "boring" fundamentals.
|
| And those devs set the wrong patterns and standards for others
| following hot behind them. The only time I can remember needing
| to dress a div up like a button was when an accordion trigger
| was just a giant button and anything passed in would be
| rendered inside, but I needed an action to the right of the
| trigger title. But those happen super rarely. You can't just
| pass in a button as it was invalid html to have nested buttons
| obviously. Yes, I know I could probably use css to absolutely
| position it or something but that takes it out of the flow and
| starts hacking about it in another way.
| Akronymus wrote:
| Also, get rid of JS based scrolling. I scroll a lot with
| pressing the middle mouse button. Too many sites break that.
| OptionOfT wrote:
| This reminds me of Microsoft's website checker in Office 365.
|
| Click a link with left-mouse, and it'll intercept the page with
| their safety checker (that doesn't work half of the time)
| before forwarding you.
|
| But middle click? No safety for you.
| croisillon wrote:
| <3 the top-border
| randyrand wrote:
| > This element does not announce itself as an interactive element
| to screen reader users
|
| Are you sure? Screen readers should be able to detect a div with
| a onclick as interactable, no? And if they can't, that seems like
| an exceedingly simple fix. I'd be shocked if they can't already
| detect onclick.
| rictic wrote:
| A click handler can be doing a lot of things that aren't much
| like a button, like letting you close a modal if you click
| outside of it, capturing mouse events for a game, or passively
| recording events for analytics. All that a click handler tells
| you is that there's some code that sometimes cares about some
| clicks somewhere inside that element.
| knute wrote:
| Also a click handler on a div isn't going to do much for
| someone who isn't using a mouse, which would include a lot of
| screen reader users.
| randyrand wrote:
| All of those seem like examples of things you'd want your
| screen reader to tell you about.
| 1-more wrote:
| I can confirm. I got decent with VoiceOver as the "guy on the
| team who gives a shit about this" (unofficial title) and yeah,
| it stinks. Also, you don't necessarily move through the page
| linearly with a screen reader; the rotor lets you jump between
| links, or jump to forms, or jump to navs. The more semantic
| your markup, the better it will be populated.
| cferdinandi wrote:
| It's worth noting that VoiceOver is well-known for being a
| lot more lax than most other screen readers. Other options
| tend to be a lot more strict around standards and what
| they'll announce.
| stack_framer wrote:
| I wonder if the "React Ry-thought-leader-guy" crowd (I love this
| not-so-subtle reference to Ryan Florence) preferred div over
| button because of the built-in styles that browsers used to apply
| to button elements.
| 1-more wrote:
| This I've never gotten. It takes very little CSS to unstyle
| them!!
| exogen wrote:
| In today's world, yes. But as with a LOT of complaints about
| "web developers!!!!" the answer is usually "because of the
| way the web WAS."
|
| Before IE became Edge (and maybe even in the earliest
| versions of Edge), there were certain styles and descendants
| that simply did not work on a <button> element, like Flexbox
| and Grid positioning. So, if your button had content like an
| icon, and you were trying to align it a certain way with the
| label, you simply couldn't use some features of CSS like you
| could with a <div>. It was a pain in the ass.
|
| In the same vein, do you remember the period where some
| browsers wouldn't allow you to make a button look like a link
| using CSS, because they thought it might deceive people and
| thus be a security issue? I do.
|
| And similarly when people complain about the complexities of
| webpack and bundlers in general, do you remember including
| the jQuery <script> tag on the page and then almost always
| needing to call `jQuery.noConflict()`? And how in those days,
| most people got even THAT wrong, because atomic <script async
| onload> behavior didn't work correctly in all browsers yet,
| so other code could actually run in between a <script> and
| its onload callback, meaning the jQuery.noConflict call was
| ineffective and something else could steal it? I remember.
| webpack fixed that by automatically scoping everything.
|
| Nowadays, a lot of those workarounds are unnecessary (depends
| what browsers you're supporting). But it's not like there was
| never a reason for them.
| 1-more wrote:
| A cool thing about a lot of the agency work I did early in
| my career is our audience was not actually the stated
| audience, it was the staff at the company that hired us.
| And one of the companies was on IE7. So yeah, I've nine-
| sliced a gif or two and done a few clearfixes in my time,
| haha. Never ran into a lot of these, but these weren't apps
| so much as brochures that happened to be online. Luckily
| enough we could control the environment pretty well to
| avoid actually needing noConflict() on jQuery.
|
| But that was in 2011-'13 and things have gotten a bit
| easier since then and it's up to us to stay abreast of
| what's possible on the platform.
| cferdinandi wrote:
| That was a big part of "thought leader guy"'s argument in favor
| of divs, but not the only one.
| donatj wrote:
| I would love to see this expanded into "Just use the HTML element
| that was built for that explicit purpose". I feel like your
| average SPA developer doesn't understand what even a quarter of
| the HTML elements are meant for and just reinvent the wheel every
| time.
| culi wrote:
| Yes it's called "just use the platform" and it's become a
| common refrain in the front-end world at least since HTML5 came
| out around 2014. Unfortunately it hasn't caught on in all parts
| of web dev but it's definitely seen as the "correct" way to do
| things
| serial_dev wrote:
| I heard it almost a decade ago in Polymer and Web components
| circles https://www.polymer-
| project.org/blog/2016-05-26-IO-2016-Reca...
|
| It's strange to look back and see that most spa projects
| still just bundle it all up into a gigantic js file...
| christophilus wrote:
| I wish the elements were just stylable, then. For example, the
| date picker sucks. I'd love to use it and eschew a JS based
| one, but my clients complain that it's ugly.
| jay_kyburz wrote:
| I vaguely remember, back in 2010, when I wrote my app, you
| couldn't style a button consistently across all browsers. They
| were grey boxes in firebox, or used other OS standard styling.
|
| We had to invent our own buttons if we wanted it to look the
| same everywhere. I could be wrong though.
| tomwheeler wrote:
| > I vaguely remember, back in 2010, when I wrote my app, you
| couldn't style a button consistently across all browsers.
| They were grey boxes in firebox, or used other OS standard
| styling.
|
| I'm sure I'll trigger a lot of designers by saying this, but
| I'm probably not alone in valuing basic usability FAR above
| styling. I much rather have an ugly button that looks like
| 90's era Tcl/TK than something pretty that doesn't behave
| like I expect it to.
| SmartHypercube wrote:
| I got bitten by this: user agent stylesheet contains "button
| {align-items: flex-start}" (at least in Chrome). The default
| behavior is "stretch". Spent an hour debugging why my flexboxs'
| sizes are wrong. I still want to use correct HTML elements as
| much as possible, but I do think using <div>s everywhere makes my
| small side projects so much easier, since I don't have to
| remember all the non-default behaviors.
| cferdinandi wrote:
| I probably should have included "if you're building for the
| frontend you should probably know CSS". Good follow-up piece.
| Thanks for mentioning it!
| crisnoble wrote:
| `appearance: none` goes a long way to resetting button styles.
| I usually make a .unbuttonify class to use or extend for things
| I want to behave like buttons (free focus, accessibility, and
| interactivity) but look like, say, a hamburger menu toggle.
| culi wrote:
| are css resets not in vogue any more? I still use them for
| all my side projects. As well as a normalize.css[0] that
| smooths over any additional browser inconsistencies. The
| original Meyer reset is definitely overkill, but there are a
| couple newer more minimal ones out there[2][3]
|
| [0] https://necolas.github.io/normalize.css/
|
| [1] https://meyerweb.com/eric/tools/css/reset/
|
| [2] https://www.joshwcomeau.com/css/custom-css-reset/
|
| [3] https://piccalil.li/blog/a-more-modern-css-reset/
| xnx wrote:
| Page makes no mention of <input type="button">. Are there any
| situations where that should be used?
| adam_beck wrote:
| From MDN:
|
| > Note: While <input> elements of type button are still
| perfectly valid HTML, the newer <button> element is now the
| favored way to create buttons. Given that a <button>'s label
| text is inserted between the opening and closing tags, you can
| include HTML in the label, even images.
| jarek83 wrote:
| It's a thing from the times when <button> did not exist. Other
| use cases were for supporting IE. Today just use button.
| cferdinandi wrote:
| I would literally never use <input type="submit|button"> for
| anything when the <button> element is an option, personally.
| Brendinooo wrote:
| Related, because I don't always get to talk about buttons:
|
| In my day job's shared library, we made a Clickable component
| that basically exists to abstract away the decision to use a
| button or an anchor tag, and resets the styles so both elements
| act the same way (both by default and when we apply styles to
| each).
|
| We'd have a lot of confusion on the design side about button-as-
| design vs button-as-function and now we don't have to deal with
| that at all anymore.
|
| And since the styling's been reset in a predictable way, it takes
| away one of the bigger reasons why people go to divs in the first
| place.
| Sharlin wrote:
| How does style reset make the elements work the same way? Links
| have vastly more features built into browsers than buttons
| jarek83 wrote:
| The type of developers that would go with <div> in such cases are
| also those that know very, extremely little about semantic HTML
| and its purpose. Then if one is challenged about using React or
| other heavy-JS framework when you don't really have to, the
| discussion will be met with utter even surprise that someone out
| there is actually not using React.
|
| The web is darn simple, but we are the place where it is made
| extremely over engineered and expensive for both companies
| (salaries and 2-3x more staff needed than necessary because of
| the bloat) and users of their products (in terms of payloads).
|
| And yet JS-heavy frameworks seems to have the best job market.
|
| Everything seems to be upside down.
| steve_adams_86 wrote:
| This is a good example of cases where LLMs can tend to write
| 'bad' code, because these patterns (i.e. reinventing wheels in
| the browser) are quite common in the wild, and LLMs tend to
| choose them over just using native features (such as buttons). I
| find myself telling Claude to revisit implementations and
| simplify them in these kinds of ways.
|
| Another good example is bizarre error handling conventions when
| working in TypeScript. Claude will come up with tons of weird
| ways of doing this, using different approaches all over the
| place, but rarely consider simple patterns like 'return an
| expected value or an error'.
| turtletontine wrote:
| These are great examples of how LLMs are great at _writing
| code_ , but pretty bad at _software engineering_
| serial_dev wrote:
| Search engines were also only good at looking up things, not
| software engineering. I find it a blessing that a human is
| still valuable in this process we call software engineering.
| And meanwhile you can use search engines just like LLMs to
| learn and discover much faster than without them.
| boothby wrote:
| Only nowadays LLMs are embedded in search engines so if
| you're looking for something that doesn't exist the top of
| the page is liable to hallucinate its existence.
| Sohcahtoa82 wrote:
| tbh, I've started to grow a disdain for front-end developers. It
| seems their favorite pastime is re-inventing the wheel, and every
| single time, they destroy something while gaining _absolutely
| nothing_.
|
| Stop implementing date pickers when <input type="date"> exists.
|
| Stop implementing smooth scrolling. _Browsers already do it on
| their own_ , and your implementation _will not work_. Really,
| just don 't mess with scrolling in general. Don't make scrolling
| have "momentum". Don't change scroll speed. One site I've been to
| goes out of its way to change how much a scroll wheel click
| scrolls the page. For fuck's sake, can someone explain to me why
| that would be a feature!? Why go out of your way to override a
| specific user preference!?
|
| All this bullshit changes expected behaviors, reduces
| accessibility, reduces the performance of your web page (and
| therefore increases CPU and battery usage)... _for no reason
| whatsoever_.
| al_borland wrote:
| > Stop implementing date pickers when <input type="date">
| exists.
|
| This still has issues in some browsers. With sites already
| having other methods from before this existed, there isn't a
| good reason to move to it, when they'll need the custom version
| for browsers that lack full support.
|
| This is the issue with a lot of newer features.
| Sohcahtoa82 wrote:
| > This still has issues in some browsers.
|
| Your knowledge is out of date. <input type="date"> been
| implemented in _nearly every_ browser since 2018, with the
| exception of Safari which was slow and didn 't put it in
| until 2021, and Opera Mini which still doesn't have it at
| all, but who the hell uses Opera Mini?
|
| https://caniuse.com/input-datetime
| Zak wrote:
| This is enough of an issue that someone made
| https://dontfuckwithscroll.com/
| HocusLocus wrote:
| A whole generation of people who click all over to find places
| that do something. People have this problem where they feel
| 'proudly vested' in learning things that just weren't designed
| well.
|
| 10 years ago someone decided that _dragging links_ is so much
| more important than selecting text, selecting text is scarcely
| possible. I 'm going to have to fork a browser to give link-
| dragging the demotion it deserves. It was probably those DIV
| guys.
| culi wrote:
| This is a great point that I don't see brought up enough. I
| don't know if I've ever purposely wanted to drag a link but I
| struggle to highlight/select some in a link every other day
| ForLoveOfCats wrote:
| I might be a weirdo but I drag links all the time as it's how I
| open links as background tabs even though there is a right-
| click context menu entry for it
|
| Unless the site is _really_ messing with events, holding alt on
| PC (Windows/Linux/ect) or Option on macOS lets you select text
| in links without triggering the link to navigate.
| ivanche wrote:
| Holy fsck! 30 years on the web and today I learn about this
| Alt/Option trick. Thank you!
| ajmurmann wrote:
| Almost as bad as copying a phone number on iOS instead of
| calling it (no idea if this is better on Android). The
| eagerness of iOS to call phone numbers which almost never is
| the thing I want to happen, is a source of much anxiety.
| Shog9 wrote:
| Android works great - lets you select the # and then gives
| you a context menu with the option to call (or copy, or
| search).
|
| ...unless someone made the phone # a tel: protocol link, in
| which case it has the selection behavior of any other link.
| Which is mostly fine, since "copy" is a context menu option
| for tel: links... unless some jerk put a tel: URL in that
| isn't the same number as what is shown in the text of the
| link, in which case it's time for some crazy hoop-jumping to
| either copy OR call the number.
| ratijas wrote:
| There are browser extensions for selecting links. It used to be
| called Select Like A Boss, now it's Drag-Select Link Text.
| tl;dr: drag horizontally to select text, drag vertically to
| drag-and-drop as usual, press and hold to select the whole link
| text.
| tomwheeler wrote:
| > selecting text is scarcely possible
|
| I find non-selectable text maddening, but I recently found an
| macOS app called TextSniper that restores my control. It lets
| you select an area with the mouse (as you would when taking a
| screenshot) and it then OCRs the text and puts it into your
| clipboard. It almost makes Google Analytics usable again.
| shreddit wrote:
| > You shouldn't, though! Seriously, just don't fuck with focus
| order.
|
| And here i am, wishing some would do just this. Especially
| creators of log in forms which make the "reveal password" button
| the next focus point instead of the "submit" button
| culi wrote:
| is pressing tab twice instead of a single time really that big
| of an issue? Messing with focus order is definitely a bad idea,
| but they could also use less semantic html to skip the reveal
| password "button". For people who can _only_ use keyboards,
| this would make it impossible to access that feature however
| throwaway106382 wrote:
| For the love of god why can't people just use standard elements
| for their intended purpose.
|
| Here's a tip for weirdo front-end devs that do this: You are not
| smarter than the people that created the spec.
| culi wrote:
| it's not about being smarter. It's about being lazy. They don't
| wanna reset the default button css in order to perfectly match
| the figma they're being contracted to draw up. They simply
| don't care and the people contracting them don't have the
| knowledge to check if shortcuts were taken
| throwaway106382 wrote:
| Yeah I don't want to work with lazy people either. Shame.
| spkm wrote:
| Just don't use animated gifs inbetween text.
| fullstackchris wrote:
| div onclick is an abomination that should be eliminated
___________________________________________________________________
(page generated 2025-10-31 23:01 UTC)