top | item 28230977

Don't attach tooltips to document.body

230 points| atfzl | 4 years ago |atfzl.com | reply

92 comments

order
[+] habosa|4 years ago|reply
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.

[+] Agentlien|4 years ago|reply
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.

[+] Pxtl|4 years ago|reply
... 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.
[+] zerocrates|4 years ago|reply
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.

[+] obedm|4 years ago|reply
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.

[+] yoz-y|4 years ago|reply
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.
[+] AdrianB1|4 years ago|reply
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.
[+] krsdcbl|4 years ago|reply
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"

[+] qwertox|4 years ago|reply
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.

[+] eyelidlessness|4 years ago|reply
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

[+] dutzi_|4 years ago|reply
You could argue that the browser does provide you with a “free”, native tooltip OOTB.
[+] xboxnolifes|4 years ago|reply
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.
[+] jokoon|4 years ago|reply
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.

[+] weird-eye-issue|4 years ago|reply
I don't consider this a bug, it's really a very minor performance issue. 80ms isn't going to be noticed by users
[+] myfonj|4 years ago|reply
As for why the parent render tree invalidation is necessary, consider

    <style>
      main:only-child * { /* ... */ }
    </style>
    <body>
      <main>lots of stuff </main>
    </body>
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.)

[+] foobar33333|4 years ago|reply
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.
[+] layer8|4 years ago|reply
> 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.)

[+] orangegreen|4 years ago|reply
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.

[+] frosted-flakes|4 years ago|reply
And that they don't work on mobile.
[+] chrismorgan|4 years ago|reply
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:

  head,
  title,
  style,
  script {
    display: block;
  }
[+] ComputerGuru|4 years ago|reply
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?
[+] sandstrom|4 years ago|reply
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`?
[+] atfzl|4 years ago|reply
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

[+] btown|4 years ago|reply
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!

[+] namelosw|4 years ago|reply
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.

[+] chrismorgan|4 years ago|reply
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.
[+] sdflhasjd|4 years ago|reply
That is typically done because some browser extensions and older JS libraries will append elements to the <body>, react would destroy these when rendering.
[+] geuis|4 years ago|reply
I appreciate these kinds of frontend deep dives.
[+] sidcool|4 years ago|reply
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?
[+] smrq|4 years ago|reply
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...
[+] GeneralTspoon|4 years ago|reply
Try any Flutter-based website and see for yourself!

Hint: It’s J A N K Y

[+] hugneutron|4 years ago|reply
The article didn’t seem to mention anything about performance in other browsers, which I find surprising.
[+] faeyanpiraat|4 years ago|reply
... Next steps are paint and composting ...

That step seems unrelated

[+] Lvl999Noob|4 years ago|reply
They also weren't discussed. Only mentioned for completeness' sake.
[+] Aeolun|4 years ago|reply
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.

[+] TekMol|4 years ago|reply
Talking about tooltips:

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

[+] FezVrasta|4 years ago|reply
Popper provides ES6 module support out of the box. What problem are you facing with it?
[+] bserge|4 years ago|reply
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!

[+] foxpurple|4 years ago|reply
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.
[+] catmanjan|4 years ago|reply
Yet another browser based leaky abstraction... Looking forward to the inevitable trend flip back to native ui!
[+] jessaustin|4 years ago|reply
Don't hold your breath...