26d ago
I'm sure there are many contexts in which this is a good idea.

For many others, though, I like to be able to press, move whatever pointing device I'm using from the hot zone, and release to cancel the action. It's like holding the chess piece.

I recently had this debate with my friend, who built this fun test to see how much latency was actually added by waiting for mouseUp: https://click-duration-timer.vercel.app/

I felt pretty strongly that I would hate triggering events on mouseDown because of how often I "cancel" an action mid-click. But I decided to add this userscript to my browser and live with it for a week:

  let preventNextClick = false;
  const interactiveElements = ['a', 'button', 'input', 'select', 'textarea'];
  document.addEventListener('mousedown', (event) => {
    if (event.metaKey) return; // allow cmd+click to bail
    if (event.button !== 0) return; // handle left clicks only
    // ignore all but a handful of elements
    const tagName = event.target.tagName.toLowerCase();
    if (!interactiveElements.includes(tagName)) return;

    // set a flag to prevent firing two click events
    preventNextClick = true;
  document.addEventListener('click', (event) => {
    if (preventNextClick) {
      preventNextClick = false;
  }, true); // use capture phase

This causes any of the interactive elements on a page to trigger their onClick action during the mouseDown phase rather than onMouseUp. It's probably not perfect, just a scrappy user script. But omg it is so much nicer to browse with this enabled. And I say that as a hater of the original idea with strong opinions.

So, if you want to have a slightly more informed opinion on the issue I suggest trying this or something like it out for a week! I can't go back to the way it was before. Everything is so snappy now.

I haven't (yet) found a case where I wished I had the mid-click cancelability I had before. I think that getting used to the idea of clicks being instant rewired my brain a bit to simply not rely on that behavior anymore.

I had an e-scooter where a double click on the mode-select button would turn on the light and respond with a little beep. A single click would just switch the mode with no beep. To this day believe that the beep always came before the second click. I tried to trick it by clicking it once and only thinking about the second click — and the beep never came. But once I committed to the second click, I swear it would beep a fraction of a second earlier than that happened. Whatever it was that the button was connected to, it was insanely fast, just immediate. My brain had been so hardwired to expect every human-machine interface to have a delay, that the button responding immediately to the second click felt unnatural, broken, magical, and honestly kind of creepy.
Some cases yes, but in plenty of cases, this wouldn’t be great.

- Browsing HN, and your scroll gesture happens to start where a link is? Before you know it, you’ve navigated away.

- Long pressing to delete an app, and the app opens in the meantime? Awkward UX.

In the majority of cases, press gestures are competing with other gestures like scrolling. Waiting until you’ve released is often the first moment that it’s 100% clear which gesture you intended. If both gestures get invoked, it will probably lead to much worse problems.

I’m sure there are cases where act on press makes sense, but I don’t think it’s as dramatic as the tweet makes out.

Funnily enough I recently noticed that the X app on iOS started doing this for me… on ads. If I place my finger on an ad while scrolling down, without fault it opens the ad overlay sheet. I guess that’s one way to increase CPC revenue
> Game developers, with simple UI toolkits, tend to get this right more often

In almost all games I play there is an inventory and a hotbar and the way you assign items to the hotbar is by dragging it. To use the item from the inventory you release the button without dragging. How else could this be done?

This reminds me of fastclick.js [1], a library developed by FT to eliminate the 300ms time lag that used to exist between click and navigate on mobile browsers. The lag allowed for dblclick events but has been removed in recent years.

[1]: https://github.com/ftlabs/fastclick

The "Leave" button in MS Teams only works on release. Towards the end of a video call, as the meeting is wrapping up, I press and hold the Leave button, waiting for the optimum moment to release...
I confess this tweet surprised me. I can't think of many games (any?) that only act on release. There are plenty that have release activation. Famously there is the video of Mario 64 using half an A press. I don't know of many that only do something on release, though. What games do this?

I am not at all surprised to know that Android had some questionable default behaviors.

I wanted to see how consistent this may be in practice on mobile iOS, focusing only on elements that are "tap" only.

- most elements are ON RELEASE

- except the phone number entry or passcode entry, these are ON PRESS

   - but the "backspace" button is ON RELEASE
I'm guessing because there are so many other interactive options on iOS (touch hold, hold drag, 3d press, swipe) this proposed paradigm is less likely to have much impact.
Very contextual. I've been appreciative of act-on-release in UIs where I can click a button with the mouse and then drag away from the button before release to change my mind. And that UI behavior has been around forever, way before touch UIs.
I am 52 and have been using computers for most of my life and there are still times when I realize I have clicked the wrong button, and slide my pointer/finger off of the button into a safe space before I release. Carmack sure does have a preference that would result in me swearing and reaching for undo, or swearing because whatever minimum viable webshit app I’m using doesn’t have an undo.
Rather obvious I would say.

I think the reason why UI designers move away from this is because on touch devices, touches have a double meaning, a short and long tap do different things, so you have to act on release.

He better not quit his day job as a graphics programmer. Act on press is a terrible design the vast majority of time and almost always has unintended consequences and is incompatible with other interactions, such as disambiguating something that can be clicked but also dragged.

> it reduces user errors

Act on press significantly increases user error because in most cases, it is not the norm, so when it shows up, users take actions they didn't mean to. I can't stand it when a button is act on press.

> and it is good UI design to favor them when possible

Saving tens of milliseconds in a button press does not automatically correlate to good UI design. Saving time is the only justification he gave, which is what you'd expect out of a graphics engine programmer. And he just suggested before this line that it would be good to have mixed behaviors, which makes no sense.

> and it reduces user errors by not allowing the focus to slide out of the hot box between press and release.

well thats one way to demonstrate a misunderstanding of many UI

In some safety critical software, it's important to do the opposite, to provide a means for a user to abort partway through the action of clicking (by dragging their mouse off the control with the button still held.)
Institutional UI/UX departments always seem to overthink this stuff and get it wrong. I would love it if there was a rulebook we could reference so this sort of thing isn't always a battle.
> This is a UI design hill I will die on... it makes the interaction feel substantially more responsive, and it reduces user errors by not allowing the focus to slide out of the hot box between press and release

Sliding out is also exactly how you cancel events we when you realize you've made a mistake by clicking on autopilot.

Though hard to say definitively which one is better without more explicit comparison of these two styles of interactions

I'm not sure this should be applicable to critical actions, like completing a bank transfer, buying shares, etc.

For non critical actions where there is an easy undo - yes go ahead, e.g. in his example for an on-screen keyboard it makes sense. If you make a mistake you can easily undo it. But not when it comes to completing a major transaction.

I disagree with Carmack on this, I'm on the other hill. The press-on-release affords me the chance to bail at the last minute. It's probably because my brain is defective, but then consider it a handicap aid! But something about the way I work, makes it that my last cognition will often happen as I'm holding down the button, and it's not uncommon for me to realize that "oh shit, this is the delete button, I meant to save!" and! With the do-on-release, I can keep holding down the mouse button and carefully move the cursor OUTSIDE the button, so that the action is not executed.

Lot's of places, I want faster response (the controls in computer games, yes, of course!) but NOT in interface elements, there I want the response on release, so I have the extra opportunity to realize my fuckup and amend the situation.

https://instant.page/ is a take on this idea for web. On mouse down or hover for an <a> element, start a prefetch.

This technique hides about 80 ms of latency when triggered on mousedown and up to a few hundred milliseconds for hover.

This makes me feel like this guy was hard to work with. His attitude just seems a bit cocksure.
I do agree with his example that a (virtual) keyboard should act on press.

Even if I disagree with the concept in general, unless you have very simple and pervasive undo, perhaps.

As much as I would also like to drop double clicks and long presses and only use fast and discoverable interactions I think that ship has sailed...

A less militant solution might be highlight-on-press. We can at least ensure the UI is as visibly responsive as possible even if actions need to wait for gestures to complete.

This is exactly how https://instant.page/ makes webpages load so fast.

It cheats your brain by loading the new page once link is pressed (or even hover). Not on release.

I just found a firefox plugin which automatically redirects x.com links to nitter:


Select (for further action, think single click of a filename in a file explorer) should occur on mousedown, that's about the only thing.

While we're talking about how things could be better, though, long static hold on a draggable item on touch devices should natively cause dragstart.

It depends. Fire guns and most controls? Yes. Self-destruct the ship? Hell no.

The whole point of having a release event is another UX usability principle: being able to undo a click or tap.

Having disabled players conducting real UAT to ensure UX is appropriate for a wide audience is also important.

If you implement act on press, and it's "destructive" in any way, and you don't have a way to reverse it, you are wrong. Carmack is usually smart, but this is a hill he'd easily die on any day of the week.
Then please die on that hill.

Cancelling an event after down press is really good outside of games.

In games holding a button down for a little or a lot longer is a good stand-in for “pushing hard” which you want the game to react to.

Not to mention this is the way that physical buttons work in the real world. People would be immensely annoyed if suddenly doorbells, elevators, light switches, etc. didn't operate until release.
This is problematic on touchscreens because:

- Sometimes the content can be scrolled, so it’s not clear when the user presses whether they intend to scroll or actually press the button. Similarly, sometimes the pressed item can also be dragged.

- Other times the buttons may be small and the user may have fat-fingered, so it’s important they can drag outside the button to cancel (or in some cases, like the keyboard, maybe select a different button).

- Some buttons have special “long press” or “hard press” actions, particularly on iOS. This is really good UI, and it only works if the button’s normal trigger occurs on release or the normal trigger segues into the long-press trigger.

- Even when none of the above apply, the user is still conditioned to expect the button will trigger on release. They aren’t going to deduce “this button isn’t in a scrollable area and is large enough and has no long-press action (or the normal action segues into the long-press action), so it will trigger instantly”.

- It almost never makes a difference to wait for the user to release. If the content loads fast enough, it will load before their brains’s reaction time (they are releasing the button before their brain can start processing new content). If you really care, to remove 0.1 seconds of latency, you can preload the content when the user taps the button, commit it on normal release, and revert it on cancel. Toggle and selector buttons have no immediate effect, so for them it never makes a difference.

On desktops it matters less whether buttons trigger on press or release, but IMO it still matters. “Long-click” isn’t common and scrolling is done differently, but there are still draggable elements, “fat-fingering”, and conventions. The thing that matters, for both desktop and mobile, is that the button or item has a “(being) pressed” state that looks different than the selected state. IMO if the button doesn’t have a pressed state, it feels more natural for it to trigger on press; but it feels more natural for the button to have a pressed state than not, and when it does have this state, it feels more natural for it to trigger on release.

UI elements that the user “taps and scrolls” (minus the text cursor) like sliders and color pickers are typically expected to react instantly to the user’s touch (and a slider or color picker in a scrollable view is bad UI, because it interferes with this). Although even these elements I’d prefer go into a “pressed” state, to indicate that if the user releases or scrolls within the control it will switch to the value at their finger, but if the user cancels (e.g. simultaneously presses somewhere else with another finger, or scrolls vertically outside of a slider) it will keep its original value.

The one place instant-trigger buttons are important is real-time game UI, where reaction time is important, hence the author’s observation. Although instant triggers don’t matter in out-of-game UI, there are reasons why they may carry over: said UI may be written in the same framework, with the same developers, or the studio may wants to make the entire game’s UI responsiveness consistent. Non-real-time games may also benefit from instant-trigger buttons, although I’m less sure of their importance in these games, it seems they are common. Perhaps a game like Shattered Pixel Dungeon would feel “delayed” if it didn’t have instant triggers, especially if you are playing it really fast, even though AFAIK time in that game is entirely determined by your sequence of inputs.

When it comes to actions (by which I mean commands) in conventional UI, all desktop platforms follow the well established convention: keyboard acts on press, mouse acts on release. This doesn’t mean that there aren’t controls that react on mouse down—focusing an input field, for example, is a mouse-down thing, and you can immediately start things like text selection thereby; and draggable things like scrollbars are also naturally exempt from this. But basically everything else, certainly things that are for taking actions, should act on release, if you’re activating them with a pointing device.

From time to time I encounter web systems that get this wrong, using keyup or keypress instead of keydown, or using mousedown instead of click¹. Most people won’t notice, I expect, but I suspect I pretty much always immediately notice and find them infuriating, because they break the universal convention—things that you’re used to being able to do, don’t work as you expect. Perhaps my favourite example of this was some system which would close some form when you released Escape—so when I had something else open above the browser at the OS level (or maybe it was even just a <select> dropdown! Actually that sounds right; I know I triggered this too often) and closed it by pressing Escape, the web page underneath then received the keyup, and so the Escape press closed two things in one go, which was never what I wanted.

If you can start executing an action on mousedown and only commit it functionally and visually once it turns into a click, go ahead. But otherwise, please don’t act on press, because it’s wrong.

The on-screen keyboard he mentions… well, I’m actually a bit puzzled by that, because it should completely obviously map press to keyboard press, and release to keyboard release, and anything else would be wrong, so how was there ever an argument, and in fact how else could you implement it? I genuinely don’t see any alternative, if you’re working on an OS that has the concept of keyboards already. Ultimately, I don’t think it supports his point at all, because he was implementing a keyboard.


¹ Note that even monitoring mousedown + mouseup may sometimes be wrong, due to nuances that can cancel the click mid-press; things being draggable is the obvious example, but I think some platforms let you hit Escape on a keyboard, or maybe have other multi-pointer quirks.

Isn't it carry over from anti-chattering/de-bouncing feature?

Most micro-processors has useful edge- and level-detect interrupt features that allows instant unconditional jump to interrupt handling subroutine(think callback functions) often used for physical buttons handling.

And one of common knowledge associated with that is, physical buttons tend to go through a transitional random state while being pressed, generating rapid succession of false on-off signals. This could trigger the interrupt detection feature, and while there will be little chances of memory leaks and no GC mess from this at all thanks to interrupt systems being static objects, it could still put system in a weird state and/or massively slow it down.

The most typical solution to button chattering problem is as follows:

  1. have the button input pin triggered for rising edge(button not pressed to pressed).   
  2. upon detection, immediately disable interrupt upon trigger, optionally send button down event to OS.  
  3. wait a millisecond, or for whatever duration the button takes to settle.   
  4. while at it, re-trigger the interrupt now for falling edge to detect button release.   
  5. on falling edge, pass the button up and button click events to the OS, or call the onClick() callback, and configure everything back to 1.  
  (0. call the hardware guy cubicle for further discussions)
... which results in classic MacOS style behavior of button press greying the button without action, and that is cute.

But the point is, it's less of a UX feature, more of hardware quirk suppression. Certainly a VR keyboard button virtually pressed by 3D spatial location of individual fingers don't require such pieces of anti-chattering code.

[expletive], I'm bad at drawing conclusions. Maybe I could say, by Chesterton's Fence principle, here the theory of Act on Release implementation is explained, and removal of fence can now be freely discussed.

Thanks, I hate it.

> it reduces user errors by not allowing the focus to slide out of the hot box between press and release

No, it increases user errors by not allowing the focus to slide out of the hot box between press and release.

Act on release. This is a UI design hill I will die on.

Yeah, in FPS or other games where reaction time matters, or just games in general, you always want to act on press.

In all other apps, act on release.

Here is the tweet:


Act on press

This is a UI design hill I will die on, and it dismays me how often and hard I have had to fight for it.

Almost all interaction methods have a “press” and “release” event associated with them. Whenever possible, you should “do the thing” when you get the press event instead of waiting for the release event, because it makes the interaction feel substantially more responsive, and it reduces user errors by not allowing the focus to slide out of the hot box between press and release.

Even a “ballistic tap”, where your finger is intentionally bouncing off the button or touch surface, involves several tens of milliseconds delay between the press and release, and most button presses have well over a hundred ms dwell time. There is a delight in interfaces that feel like they respond instantly to your wishes, and the benefit to every single user is often more important than additional niche features.

Game developers, with simple UI toolkits, tend to get this right more often, but “sophisticated” app designers will often fight hard against it because it is mostly incompatible with options like interactive touch scrolling views, long press menus, and drag and drop.

Being able to drag scroll a web page or view with interactive controls in it is here to stay, and nets out way better than having to use a separate scroll bar, but there are still tons of fixed position controls that should act on press, and it is good UI design to favor them when possible.

In the early days of mobile VR, the system keyboard was a dedicated little OpenGL app that responded instantly. With full internationalization it became prudent to turn it into a conventional Android app, but the default act-on-release button behavior made it feel noticeably crappier. The design team resisted a push to change it, and insisted on commissioning a user study, which is a corporate politics ploy to bury something. I was irritated at how they tried to use leading questions and tasks, but It still came back one of the clearest slam-dunks I have seen for user testing – objectively less typos, expressed preference, and interview comments about the act-on-press version feeling “crisper” and “more responsive”.

So, I won that one, but the remaining times I brought it up for other interfaces, I did not, and you still see act-on-release throughout the Meta VR system interfaces.

Extremely anecdotal - but for whatever reason I read the first two paragraphs thinking JC was talking about marketing. I was both quite confused by the fact that you should have 2 events, one for the press, and one when you release. I thought that "the thing" was some allusion to a marketing concepts that I wasn't familiar with. I was also quite saddened that John Carmack would post about marketing. Turns out I just need to learn how to read.