Hacker News new | past | comments | ask | show | jobs | submit login
Don't attach tooltips to document.body (atfzl.com)
230 points by atfzl on Aug 21, 2021 | hide | past | favorite | 92 comments

This is an excellent and technically deep post, I learned a lot reading it and I'm going to make sure I'm using my tooltips properly.

It's a shame that most of the comments here are just people criticizing web dev frameworks and browsers.

This issue of needlessly forcing the system to recalculate a tree of positions and bonds is also common in other UI contexts such as desktop applications and game UIs.

In fact, in games it also happens with the transforms of objects and has been the cause of a number of performance issues during development of AAA games I've been part of.

... this post perfectly encapsulates why I hate web development. A painful and easy to miss bug when trying to reimplement a GUI feature that's been available in every decent GUI framework for over two decades.

I really wish we'd gotten a couple more useful native controls back when there was any will to add that kind of stuff... It's sad/annoying to see all this reimplementation of simple stuff like comboboxes, and then all this extra effort to make it work OK in different form factors... The great experience of the select element that just gets you a mobile appropriate native UI for free is unavailable for so many simple cases.

Last I checked the form additions from HTML5 were still pretty spotty in support, several don't really have a real world use case, and nobody wants to make any more really.

The "problem" with native controls is that they might visually clash with the design of your website. That's why everybody implements their own controls or uses libraries like jQuery. And sadly, that's probably why we don't have good default controls.

> The "problem" with native controls is that they might visually clash with the design of your website.

CSS can fix that once good native controls are implemented.

That requires the ability to style things like the dropdown of the combobox (e.g. to add rounded corners, change the background/border colour), and the rows for each items (e.g. adding padding, and divider border styling). At the moment, that is difficult because they are not part of the HTML box model. And what about styling controls like date input or colour pickers?

Another issue is styling checkboxes to use custom images for the different states (including hover and pressed styling).

The CSS UI spec (https://www.w3.org/TR/css-ui-4) doesn't detail any of that, and the WHATWG HTML spec only defines the values of input fields (e.g. https://html.spec.whatwg.org/#the-input-element), not what parts of things like a date control are available and how to style them.

People use JS to implement basic things like scrolling a page, usually resulting in a experience that’s uniformly worse than the native one would be

I have trouble seeing this as a problem, especially with electron and other local web-tech stacks.

I miss the days when clickable things looked clickable.

> I really wish we'd gotten a couple more useful native controls back when there was any will to add that kind of stuff...

We're trying, and we need help: https://open-ui.org/

Come say Hi on Discord, anyone who has written a JS control has input that the project needs.

This perfectly encapsulated why I LOVE web development.

You can debug one of the most complex softwares in the world (a browser) so effectively you can understand what you did wrong and fix it.

Until a browser update changes the behavior or different browser engines have different behaviors.

Web makes it super easy to build custom components compared to something like Qt, GtK or even UIKit. One of the reasons why web UIs are common is that people want more than tables buttons and forms.

I literally make a living tuning React Native shitheaps:

On mobile, as a rule, the second a design transcends things like tables, buttons, and forms is when the “lower level” native APIs start getting broken out.

Wrapped in nice little JS/TS APIs so nobody freaks out, of course.

React Native is not web, it’s the lowest common denominator of all platforms, so your experience is not surprising.

Having developed custom elements in both web and native, I felt that web was easier and more predictable than native. (For example adding clipping to images on iOS throws away most possible optimisations resulting in abysmal FPS) Of course the “best possible” UI is also slower and worse than what could be done in native.

(Also, on mobile I firmly believe that native is the right way to go with the current tech)

Not even a bug, it's one of the inner working things you may or may not know about. I see it more than a trap than a bug. Honestly, there are other parts of IT that have it, the most familiar to me is SQL where you can run the same query in 10 seconds or 20 milliseconds and only experienced DBAs can tune it properly, in many cases without touching the query itself.

Traps are bugs. If you're making a library and you don't treat traps as bugs, it's a bad library.

don't agree at all. If the "native thing" came at an overhead, your hands would be tied. If the "native thing" didn't expose api for the styling you wanted to do, your hands would be tied.

webdev is incredibly flexible by the very nature of "build it yourself", and that's a good thing.

Having performance impact from badly optimized implementation is a testament to this flexibility - what you are saying is akin to "C is bad because i could fk up memory"

I am trying to implement drag and drop of raw text and html (html is mostly Vue components) inside contenteditable="true" to move it around. Like in a WYSIWYG editor.

It is insane how complicated this is. Then you need to consider the differences between browsers. Ultimately you have to start using a library. And integrate that library with the framework and then hope that the framework won't have a major technical overhaul like Angular or Vue had.

Most of the time you just sit there thinking what will be the best approach and start to get more demotivated the more you dig deeper into it.

It is hard.

CKEditor would have solved most of my issues, but their licensing is absolutely crazy. I'd have to contact them to get an offer to use it for normal internet usage, but if I don't know if it will work, and if the site will be a success, then it simply does not make sense to contact them. 37 USD for 25 users? Or getting a custom contract where I don't know how they will change it in the future? I don't understand what assumptions they have about the usage of their editor, but just embedding it into a blog or something similar, where you don't really know how many users you will have, definitely isn't one of them.

It feels weird to me that you are complaining about the complexity of WYSIWYG editors then proceed to complain the licensing cost of CKEditor which would have solved that very complexity. Wouldn't that mean the complexity of WYSIWYG editors is so high that such a business model works?

I'm not even sure if it really fits my case, since the editor would need to be able to create Vue components which maintain the reactivity. TinyMCE breaks all reactivity as soon as it "wraps" it all in the editor. CKEditor apparently has a way to do this (up- and downscaling), but there is the very unclear licensing issue. One active user is a user which has used the editor once in a month. So, for example, one which just signs up to check out the service and then does nothing with it ever again and doesn't subscribe.

So if I invest my time into learning this upscaling/downscaling issue, which can get complicated with a Vue component, all this in the context of prototyping the entire app, where the primary functionality gained by CKEditor the ability to enable drag and drop (move) of components as if they were pictures, it seems like overkill, since directly manipulating the DOM to move elements appears to be a a much more simple task.

I've made a test wit ondrag, ondrop and what JavasScript has to offer and it mostly works, but there are some small issues which I just can't resolve and don't know if I can resolve them if I invest more time in that direction.

So currently I'm checking out drag and drop libraries, which mostly seem to fit the purpose, but also have issues.

This is what I was getting at with my initial comment, that it's so hard to make these decisions if the outcome of the paths is so unclear. It's all a struggle between decisions and their tests which need to be made.

Assuming CKEditor would solve the issues for me, then the initial cost would still be to high. That would be different with a stable stream of income, but new services usually don't have that.

Free for up to 5 active users per billing period? This would be take 5 users to just check out the service and then that's it for the rest of the month. 37 USD for 25 active users per billing period? Simply not doable for me in the context of a startup.

> What is the minimum length of subscription-based software licenses? 12 months.

That's 444 USD for 288 potential users which wouldn't get charged more than 2 or 3 USD per month.

I'd suggest you to contact sales to learn the details of custom licensing options if you haven't already, also to make sure you're understanding the active users correctly for your case.

It still offers an open source option so you can test all its limits and see if it fits your case or not. Also if your project is not proprietary there is still the free for open source option in case your project is not compatible with GPL2+.

Have you looked at TipTap 2? Sounds like it might fit the bill for you!

Someday soon, someone will port WebKit to WASM, WebGL, etc.

Run your virtualized browser within any browser.

Its only complicated if your HTML is modified HTML.

The time you’ll spend building it yourself is worth less than 37 USD?

Worth noting:

- browsers have had native text tooltips for at least 20 years

- there are active proposals intended to address richer tooltips and similar use cases

- adding new controls to the web is a complex matter because there are a lot of stakeholders to consider, and a lot of consensus to build among implementers/standards authors

- complaints about missing UI features on the web often overlap with complaints about standards bloat and browser bloat

- this article is rich in technical information that’s applicable more broadly than the tooltip use case, and maybe every single article about anything web on HN doesn’t need to be drowned in generic myopic complaints about the web

You could argue that the browser does provide you with a “free”, native tooltip OOTB.

I see this comment on every single post about a difficult thing to do in web, but I never seem to see it in the countless articles that also show up about similar edge-case bugs in non-web development. Odd.

Same here. Got a job to do some java. 6 months later, I had to learn angular. 6 months later I was not in the company anymore.

HTML was not designed to be dynamic. There are too many redundant feature of HTML/CSS/JS, and honestly I would make everything obsolete and design a new document format with a open binary format.

Exactly. HTML was a document markup language. Articles, etc. Some forms.

We're now building applications. Applications have a totally different layout model. Only recently we're able to use flexbox. But it's insane. Just build the layout / application in something that really works (any of platform UI toolkits / markups), and use HTML for document flow.

I don't consider this a bug, it's really a very minor performance issue. 80ms isn't going to be noticed by users

this is exactly why SPA's get a bad rep: developers think an 80ms delay on a minor render operation is acceptable

The same could be said for php, c, or even basic.

They get a bad rep, but it's perfectly possible to create something secure, stable, maintainable and performant

You might be surprised just how fast 80ms really is. Again I'm not saying this shouldn't be addressed if it's causing noticeable issues but labeling it as a bug just seems strange to me (but that label wouldn't change the priority for me by itself)

> You might be surprised just how fast 80ms really is.

it's, like, five frames on a slow monitor. missing a single frame is already bothersome and worthy of bug reports.

It's noticeable if something is moving because that won't look smooth. But a 80ms delay will be very hard to notice. An average reaction time is around 300ms.

With all the downvotes I'm getting I might be missing something though :P

You're not wrong about 80ms being a "small" amount of time, but you're saying that in absolute terms. Native UI tool kits for decades now have targeted <100ms latency[1]. That includes processing user input and rendering. 80ms for part of a render operation spends almost your whole budget.

The sum total of ignoring this kind of performance footgun is why apps like Slack feel so crappy. You can't get into the flow because it's a pile of high-latency, asynchronous interactions. I haven't used Photoshop in a long time, but back in the early 2000s even on my Compaq with 32MB of RAM it was snappy. I can't imagine using something as complex as Photoshop built as an Electron SPA and keeping my sanity.

[1] https://stackoverflow.com/questions/536300/what-is-the-short...

> An average reaction time is around 300ms.

just because human's reactions are slow, does not mean that humans do not notice. In music it's routine to have people complain when latency goes above 15 ms and it was recently shown that humans could notice in some physiological way down to half a millisecond of latency.

Do you have a source for the half a millisecond part?

Just curious

It's very minor, but when it happen many times, it'll be noticable. It's proven because author start the investigation.

It won't be a problem if the tooltip has delayed appearance by 80ms, but it holds the process. So the site will have a 80ms stutter everytime a tooltip appear.

Which generally won't be noticed but it depends on the site. I'm not saying it isn't an issue just that I wouldn't call it a bug. Certainly not something so bad that it would turn you away from web dev. I mean we even have the tooling to track it down fairly easily

It's a bug. I don't care for your semantic separation of issue/bug and neither should you. Pointless distinction for the sake of ego protection. It is unwanted behaviour, therefore a bug.

Alright I guess we will just have to agree to disagree. For me, if an action takes slightly longer than it could take but isn't significantly impacting UX then I don't personally think of that as a bug. Maybe I just don't understand the impact this particular issue had

"Minor" performance issues add up quickly when there are more of them. And with this attitude there will be more of them

I never said it shouldn't be addressed if it is impacting the user experience

As for why the parent render tree invalidation is necessary, consider

      main:only-child * { /* ... */ }
      <main>lots of stuff </main>
When second node is appended to <body> our CSS selector no longer matches so the rule stops being applied and content of the <main> is no longer styled.

When there is (next) sibling wrapper present, anything what happens inside it cannot affect the <main> in our example: in CSS there simply is currently no way to target element according it's next sibling inner structure. (There is one for previous sibling: `prev:empty + next {}`: when prev stops being empty, rule stops to match.)

It would be nice if the browser title text feature didn't flat out suck. Why is there no way to show tooltips immediately rather than having to wait a few seconds. Seems like every website reimplements them because the browser ones are useless.

> Why is there no way to show tooltips immediately rather than having to wait a few seconds.

Because you don’t want tooltips to constantly flicker up when moving your mouse around. This should be a user preference setting, like e.g. double-click speed. (It is on Windows for native tooltips, via the registry.)

I agree, I hate how long it takes for the title attribute to show up when hovering over elements. It takes a few seconds, where any decent tooltip will take maybe 0.5 seconds or so to show up. I'd love to be able to style the title attribute for length of time to show up.

Fortunately tooltips are pretty easy to make these days. You don't need Javascript at all to make a nice tooltip. But again, it's a tooltip - it's been done so many times before that it'd be nice to have a native browser version.

And that they don't work on mobile.

Nor do custom tooltips though because the majority of websites and apps fire them on a mouseover event.

Tooltips on mobile are tough.

Tooltips usually are on links. For example here on HN, hover over "11 minutes ago" in the comment header and it shows the time. Could this be made available to mobile users? Seems tricky. My first thought would be to show it when the user taps and holds. But that also triggers the browsers default context menu for links. So it would make a murky experience.


This is about the best and most intuitive solution you could come up with to this problem. Sadly I believe the Samsung Galaxy S4 was the only phone that supported this without an S Pen so you could simply hover over the screen with your finger. I wish it was a standard feature on all phones.

I wonder if a hover over event would be good for UX.

I think most of the current displays can detect a finger hovering over the display but not necessarily touching it.

It might be a complete disaster though, just wondering how that info could be used.

If used sparingly I think it would be really good. Just for UI hints, not for anything critical. A universal "what is this?" input for anything on the screen.

>My first thought would be to show it when the user taps and holds. But that also triggers the browsers default context menu for links

The first doesn't exclude the second. That's the way how https://xkcd.com/ is doing it. It just shows both.

A remark on the two diagrams following “Then the CSS is parsed and browser creates the CSSOM (CSS Object Model)”: they show body as the root, but would be more accurate if they showed html as be the root and head as hidden by `display: none`.

Consider this style rule set which does just what it looks like:

  script {
    display: block;

I imagine another option if you need to assign a node to a class and then measure its size/location (which is probably quite often) that you can basically take some preliminary/initial values, attach the class, and use an onresize handler to trigger a remeasurement once the reflow has completed at a pace of the browser’s own choosing?

At the bottom of the article they mention:

  What happened here? The tooltip was attached to the tooltip container and not to the body.
  This invalidated a much smaller subtree, which was the tooltip container. The tooltip container 
  is not visible in the page, so modifying it doesn’t invalidate the complete page render tree.
  If the tooltip container would have been visible in the page, then the complete render tree 
  would be invalidated but in this case only an independent subtree was invalidated.
So the tooltip container needs to be hidden with e.g. `display: none`?

Having `display: none` is not required for the tooltip container.

The container is an empty div which is not visible, and even after adding children which are not directly visible `inside` this div keeps this container div invisible.

You can check out some examples in https://github.com/mui-org/material-ui/issues/27879

Thanks for the update! :) Awesome article btw!

Also curious about this: what creates a "boundary" that prevents an invalid subtree from invalidating the parent? Does it need to be hidden, or simply placed absolutely etc.?

The article is so well-researched otherwise that I'm sure the OP knows the answer to this, but it frustratingly didn't make it into the article itself!

It's the same reason that most React apps start with ReactDOM.render(<App />, document.getElementById('app')) instead of ReactDOM.render(<App />, document.body).

IIRC there were many tutorials in the early days of React that mentioned this.

I’d count that as largely unrelated. This is purely a performance optimisation, whereas mounting to an element other than the body is so that you can be somewhat more confident about the DOM inside your chosen root being in the shape you desire, since it’s common for third-party scripts, browser extensions and the likes to add children to the body (start or end), which can mess with VDOM resolution.

That is typically done because some browser extensions and older JS libraries will append elements to the <body>, react would destroy these when rendering.

And Do: profile your web app!

I appreciate these kinds of frontend deep dives.

I am not a UI dev, but I have seen some noise about using Canvas based text rendering. What is HN's opinion on this?

Sounds awful. No accessibility to screen readers. It's raster-based so you can't zoom. No text selection or copying. And that's just what I thought of off the top of my head...

Totally agree.

There is one reason I can see for using canvas based rendering generally[1] and that is if one really really wants to avoid someone from copy-pasting or indexing the page easily[2].

[1]: valid use cases for using canvas exists.

[2]: as someone who has digitized a couple of documents I'd say the effort is just above copy paste (with my tools it is copy, paste, OCR to clipbord, paste, verify)

Shouldn't screen readers use OCR? I mean OCR is basically a solved problem, and there are situations when you want to read what's in an image, or when the HTML is a mess.

There's more to screen readers than characters, otherwise we wouldn't even need aria attributes.

Also OCR is a solved problem if we ban any form of display/script font types.

Yeah, you'll probably get the best experience if the web developer specifically designs for accessibility. I guess the problem is that it doesn't happen as much as we'd like.

Try any Flutter-based website and see for yourself!

Hint: It’s J A N K Y

The article didn’t seem to mention anything about performance in other browsers, which I find surprising.

... Next steps are paint and composting ...

That step seems unrelated

They also weren't discussed. Only mentioned for completeness' sake.

I mean it’s a typo.

Look up “composting”.

I was just joking, the article is excellent.

And all these years I thought composting was using an ActiveX/OLE/XP/COM component like XMLHttpRequest to POST a message to the server.



Ah as in COM Posting.. I have no idea what all this is about though.

Having worked with React a lot. I could see the invalidation answer coming from a mile away.

Glad all that knowledge is useful in different contexts though.

Talking about tooltips:

Did anybody get Popper to work as an ES6 module? I tried for a while and gave up.

Popper provides ES6 module support out of the box. What problem are you facing with it?

Really insightful.

Wait, you guys use tooltips?

Some websites don't even have text accompanying their unintuitive but kewl looking icons.

The future is now, old timers!

Tool tips are bad ui because they are invisible normally and are completely absent on touch inputs. Either use an icon so universal it needs no tip or use text.

Yet another browser based leaky abstraction... Looking forward to the inevitable trend flip back to native ui!

Don't hold your breath...

Yes it’s more likely say Microsoft gives up on desktop ui and says meh… use electron!

Like for 'Teams'. But that is probably more of a result of not having a team of developers with a clue and management outnumbering developers five to one. You know it's true when they prioritise Salesforce integration of cut and paste working.

Some other major electron apps are pretty OK.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact