-
Notifications
You must be signed in to change notification settings - Fork 675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[css-ui] Standardize tooltip styling and expose as ::tooltip
#8930
Comments
This looks very cool! I love the idea of moving more things into a known space. 👏🏼 👏🏼 👏🏼 If this was the way forward, would we need to do some work on the accessibility side around |
We had been (briefly) discussing this in open ui as well. Here's the issue that I had posted to open ui (which pales in comparison to the detailed issue @LeaVerou opened here), after having discussed this with @mfreed7 and @aleventhal. @gregwhitworth had suggested we open an issue over here... does this need to be talked about more in open ui? or can the csswg move forward with this, and bring specific questions/asks to open ui to move those potential tasks forward? |
The problem mentioned in the “Customizing display triggers” section is easily solved by putting Then it will be possible to display a tooltip on The content can be overridden in this way: @container style(content) and (not style(content: none)) {
content: 'Hello World!'} |
There is also an option to add But this is speculative, as the mechanics of this would need to be explicitly specified in user agents, and this rules out noncommon languages. And this, in turn, will allow us to move away from the keywords dependent on the cascade and reduce the previous block of code to: @container not style(content) {…} |
Bit of a side track, but you kind of provided a prompt:
I don't inherently have much appetite for tool tips with fully arbitrary content. At the same time, full on i18n does require more than plain text. And general text semantics do too. Drawing the line is tricky though:
Most of that doesn't seems wrong in a tooltip, but we're quickly getting close to arbitrary content. (The last two are starting to feel like a stretch, but just looking on this github page and hovering a username gets you tooltips with Anyway, I think solving this here is probably out of scope for this issue, but it would be good to make sure that the solution we pick for this issue can scale to that too, because as @LeaVerou said, it would be good to be able to deal with:
|
By the way, looking at #7845, the tooltip pseudo-element is somewhat similar to So it's more logical to create an |
I love this and think that this is a quick win for web UI authors.
I think this piece should move to Open UI as we've discussed numerous times as popup landed that we'd need to introduce various popup type elements that people will reach for the popup API with manual or hint and probably get some of the a11y wrong (tooltip being the most commonly referenced).
I'm personally in favor of V1 leaving this as magic as you noted for MVP.
Yeah, that is my thought as well. The UA stylesheet should have a recommendation of leveraging anchor-positioning, or at least not inhibiting the support for it (eg: for all I know historical implementation details make it so anchor positioning will have little to no effect). For example, Chromium allows titles to escape the window bounds so this will need some level of discussion not only of implementation but also security (maybe not since tooltip is ephemeral due to only occuring on That doesn't mean that The name Thank you again @LeaVerou so much for raising this and with the Open UI community, we greatly appreciate it! Also, thanks @scottaohara for at-mentioning me so that this popped up in my inbox :) |
Summing up and slightly rethinking my previous message thread, I suggest:
/*/ ua /*/
[title] {content: attr(title)}
title {content: from-markup}
/*/ host languages /*/
:is(title,[title]):not(:focus-visible,:hover) {content: initial} |
Re system colors, InfoText and InfoBackground already exist and they were for this purpose iirc. As proposed in comment 0 this would be an extra unconditional per-each-element pseudo, which I don't think it's desirable. In practice, at least in Gecko, the tooltip is shared between all elements. Adding an unconditional pseudo-element is unfortunate performance wise, because it forces the style engine to compute the styles for it all the time. Doing it conditionally might be better, but then we need to figure out what the condition is. Other tricky thing apart from the "tooltips might want to escape the viewport if they are too long", is that positioning is tricky. If you use a bigger mouse size you might want to shift the tooltip more. This is hard to do without exposing the cursor size to the website, which we might not want to do. |
This is discussed in #8639 and in #8315. Sebastian |
I think this is a security concern. This would be troublesome if it expands the window bounds:
|
We could change the syntax to style the tooltip shared across the whole document (e.g. something like I wonder if some of these mitigation strategies may make implementation more feasible:
With the current proposal, positioning is still magic, so this shouldn't be a problem for L1.
While clicking on the tooltip today is impossible due to the mechanics, conceptually I don’t think clicking on it is supposed to propagate to clicking on the element, so even if the tooltip tricks the end-user into clicking on it, nothing much would happen. Or is the risk that it will trick the end-user into clicking somewhere outside the browser window? In that case, would it make sense to make it trap clicks but not propagate them? But even if — worst case — styled tooltips had to behave like JS-created ones and could not escape the window bounds, I think that is an acceptable tradeoff for authors (since that’s exactly the tradeoff they are making right now). It would be very useful to hear from Blink implementors too (@chrishtr @bfgeek @dbaron @lilles @andruud ?) |
There are also the error tooltips from html5 validation |
Thanks for raising this issue! So as you mentioned, OpenUI is working on a But it's important that the developer story is clear. To me, this seems to make the most sense:
If folks are roughly onboard with that split, then in my opinion, this issue ( Goals:
Non-goals for
|
Regarding History: This sounded familiar (as in I thought I had proposed something similar a while ago), and it turns out I had proposed exactly a "tooltip pseudo-element" nine years earlier 🙈😭 https://lists.w3.org/Archives/Public/www-style/2000Apr/0014.html Note that the year 2000 was before the WG switched to the "::" prefix for pseudo-element selectors, so all pseudo-elements and pseudo-classes used the single ":" prefix. (Originally published at: https://tantek.com/2023/195/t1/) |
@tantek Thanks for sharing this! I just updated the first post to include it. |
In preparation for the F2F, I think these are some questions we need to answer:
IMO:
|
Love this proposal; we could replace a lot of unnecessary web components by opening up certain access. Since much of the above is very detailed, I'd like to summarize a few properties that I see used in web components replicating this element:
|
The CSS Working Group just discussed
The full IRC log of that discussion<fremy> lea: proposal as of a few days ago<fremy> lea: tooltip styling has been brought up multiple times <fremy> lea: first was tantek, but there were many other ones <fantasai> s/times/times by multiple people since 2000/ <fremy> lea: every single time, there was little pushback <fremy> lea: yet it never went anywhere <fremy> lea: many websites have custom code to style tooltips <fremy> lea: and most of these stylings are not very fancy <fremy> lea: mostly color, background, font-style, customizing the delays... <fremy> lea: because browsers sometimes wait too much <fremy> lea: but all of this requires chaning the markup, because the element must wrap the location <fremy> lea: so this is pretty heavy-weight, and it's easy to forget some accessiblity requirements <fremy> lea: so, I really think we should do something about it <castastrophe_> +1 lea I argued so hard against our library building a tooltip web component at work <fremy> lea: and the most common proposal is a pseudo-element acceting a few properties <masonf> q? <masonf> q+ <fremy> lea: since the tooltips can escape the window bounds, it could make huge tooltips and confuse the users if everything is customizable <fremy> lea: but some properties sound fine <una> q+ <fremy> lea: later on, we can add positioning, maybe using anchor positioning, but magic is fine for MVP <gregwhitworth> q+ <fremy> lea: content itself can probably be magic too, because SVG and HTML do this differently <fremy> lea: keyword vs totally magic, not that important <fremy> lea: we can narrow this down later <fremy> lea: later on, we can add html elements, attributes, focusable, etc... <fremy> lea: but I see consensus on the basics <fremy> lea: so, are there implementors that are concerned about this? <gregwhitworth> note, I'm not an implementer anymore :P <fremy> lea: (also, maybe javascript-created tooltips?) <castastrophe_> A reference for anyone interested in Adobe's tooltip web component: https://opensource.adobe.com/spectrum-web-components/components/tooltip/#example <fremy> lea: maybe in that case, bound to the frame <castastrophe_> And an example from Shoelace: https://shoelace.style/components/tooltip <masonf> q? <fremy> lea: so, what are the constraints holding us back here? <gregwhitworth> ack gregwhitworth <emilio> q+ <astearns> ack masonf <fremy> masonf: thank you for bringing this up <masonf> Shameless plug for popover=hint and hover triggering: https://open-ui.org/components/popover-hint.research.explainer/ <fremy> masonf: I pasted our shim in the chat, a more complex version of this <ntim> q+ <fremy> masonf: but for most use cases I have seen, a few styling would go a long way <fremy> masonf: I would love it to have the tooltip in the window bounds, so that styled tooltips are consistent depending on how much they are styled <fantasai> s/complex version of this/complex version of this using popover/ <fremy> masonf: I would prefer some things to remain magic, like delays, but ok <fremy> masonf: html uses the title element, but also some aria attributes <astearns> ack masonf <astearns> ack una <fremy> una: thank you for opening this issue <myles> q+ <lea> q? <fremy> una: the first thought that comes to mind, can this also style "form error messages" <masonf> we should support the title attribute for HTML, or the <title> element with svg. <fremy> una: does that also apply to "alt text" over images? <fremy> una: maybe, this can be a "style bag" rather than a pseudo-element <lea> q+ <emilio> q- later <fremy> una: but, if you have a popover, that gives you multiple elements, and more flexibility <fremy> una: so, the limitations of this proposal, are they acceptable enough, is my first question <fremy> una: my second question, is that, how does this related to other features like alt text <astearns> ack ntim <SebastianZ> q+ <fremy> ntim: outside of the window bounds, we would want to filter down to a list of properties <masonf> q+ <fremy> ntim: also, probably some constraints like size or box-shadow <astearns> ack myles <fremy> myles: further than that, tooltips ship with the OS, and the platform usually don't allow much styling <fremy> myles: so, one limit, I would start with what the platform allows <gregwhitworth> q+ <fremy> myles: also, tooltips outside the window, requires nsWindow etc... <fremy> myles: this is costly if we want to do that <fremy> myles: but I understand that from the issue, the benefits are also quite high <fremy> myles: so, this is not "easy" at least <fremy> astearns: the rest of the proposal doesn't get to that bar? <astearns> ack lea <fremy> myles: yes <fremy> lea: I think errors for form controls are a different pseudo, because they have different constraints <astearns> s/the rest/the hard part is displaying outside the window. The rest <fremy> lea: there are commonalities, but also major differences <fremy> lea: I'm not seeing the alt text connection, which I think is more of a ::part() I think <una> q? <fremy> lea: to reply to ntim, I would definitely favor an allow list <fremy> lea: but, just an allow-list might not be the whole story <fremy> lea: I think many authors want padding, rounded borders, etc... <fremy> lea: to reply to myles, I think this would generate non-native tooltips <myles> q+ to reply to that <fremy> lea: because what authors do today is this <gregwhitworth> ack gregwhitworth <fremy> una: what do you think of popover=hint? <fremy> lea: it can probably solve some, but it requires a lot of code, and doesn't play natively with title attribute etc <fantasai> s/what do you think of popover=hint/do you think popover=hint solving these problems? <fantasai> s/solving/solves/ <gregwhitworth> I agree with Lea on this <fremy> lea: more complex use cases would like it <astearns> ack myles <Zakim> myles, you wanted to reply to that <lea> q? <fremy> myles: if this is not native tooltip, for us this is not a tooltip <fremy> myles: I would not want to call this a tooltip at this point <gregwhitworth> q+ <astearns> ack emilio <fremy> emilio: indeed, we need to answer whether the content area is enough (even for iframes) <fremy> emilio: if not, non-native tooltips are not ok <lea> q+ <fremy> emilio: but we already discussed this for <selectmenu> elements <TabAtkins> These are conditions that people already live with when they're using the custom JS-driven versions. <fremy> emilio: so, if we are, this seems workable <fremy> emilio: if we don't think this is sufficient, I would not think that this is doable (in a reasonable amount of effort) <gregwhitworth> note, only when ::tooltip is present <fremy> emilio: so, would browsers engines be fine with that? <fremy> emilio: and I have the impression that myles isn't confortable with that, maybe? <fremy> emilio: personally, I guess I'm fine, but needs some thoughts <lea> q? <fremy> astearns: TabAtkins replied on IRC that people today have those limitations, so those are probably ok with them <gregwhitworth> not if you don't use ::tooltip <fremy> emilio: but those aren't native, right? <fremy> TabAtkins: yes, they override <astearns> ack SebastianZ <fremy> SebastianZ: I wanted to say more about the security issue <fremy> SebastianZ: the native tooltips should still be able to actual document <fremy> SebastianZ: right now, UAs can clip the text etc..., UAs can create new rules based on size etc... <fremy> SebastianZ: do we have concensus that this is something that should be worked on, at least? <masonf> I'll rejoin <astearns> ack masonf <fremy> masonf: <confusing echo> <astearns> ack gregwhitworth <fremy> gregwhitworth: personally, I never envisioned the non-native tooltips to escape the bounds <fremy> gregwhitworth: and I think, as an author, that is reasonable <fremy> gregwhitworth: but even then, we can start with simple properties anyway <fremy> gregwhitworth: una pointed out alt text, and some sites use them as a tooltip in some cases <fremy> gregwhitworth: also, agree with myles, maybe this shouldnt be called a tooltip <fremy> gregwhitworth: but "the box that pops up when tooltips happen" <gregwhitworth> +1 to masonf <fremy> masonf: also, pointing out, many sites refuse to use these tooltips <lea> +1 to masonf too <fremy> masonf: and these sites accept the trade-off about off-bound positioning <fremy> masonf: personally, I don't even see that native tooltips are that necessary <fremy> masonf: I would not mind a single path, custom ones <fremy> masonf: they would be simpler <astearns> ack lea <fremy> astearns: removing is difficult on the web platform, but that's an interesting idea <fremy> lea: can we get some data about what tooltips can do on native platforms? <fremy> lea: that would help shape the discussion <fremy> lea: also, if it behaves like a tooltip, I feel it should be called a tooltip <fremy> lea: scrollbars were in that list of strange things once, but we resolved that built-in customization is better than wild hacks <masonf> astearns, the behavior of the title attribute (generating a "tooltip") is not standardized, so we're not really removing something. We're better defining it and making it more developer-friendly. <emilio> q+ <fremy> lea: mutltiple codepaths are fine on the web platform, like for <button> so I don't buy that objection <astearns> zakim, close queue <Zakim> ok, astearns, the speaker queue is closed <fremy> lea: if we can get rid of the native ones, I don't mind personally <fremy> lea: eventually, we can probably find constraints <fremy> lea: most sites that have enough resources to make a choice <fremy> lea: do not use the native ones <astearns> ack dbaron <Zakim> dbaron, you wanted to comment on alt text <una> +1 will be much easier to build without expanding window bounds and that doesn't sound like a top requirement to support authors here <fremy> lea: also, I would object about "title" as the name, because "title" was an odd name <fremy> dbaron: some feedback we once got about alt text in tooltips <TabAtkins> Basically, webcomics. <fremy> dbaron: we stopped doing this by default <astearns> ack emilio <fremy> dbaron: because alt text was used as a hack, instead of a real description <fremy> dbaron: so, this change was intentional <fremy> emilio: multiple codepaths are fine, but also the difficulty of them is important <lea> q? <fremy> emilio: for me to become more serious about this, I would like to hear some consensus from implementors that the bound restriction <lea> emilio: Of course the code path is different for buttons, my point was that from the author side there is precedent for rendering going through a different code path once CSS is applied. <fremy> emilio: if we get consensus on that, I'm fine with this <astearns> ack fantasai <lea> We have "make simple things easy and complex cases possible" in our TAG principles :) <fremy> fantasai: personally, I agree with lea, we need to bridge the gap between "you control nothing" and "you have to implement javascript, accessibility, etc..." <lea> s/complex cases/complex things/ <fremy> fantasai: right now we don't have that middle ground <fremy> fantasai: I also feel like if it looks like a tooltip and behaves like a tooltip, let's call it a tooltip <fremy> fantasai: and for the content, I think we are ok with using the same text as it would do today <fremy> fantasai: I think it's fine, ::tooltip should allow you to style it <fremy> fantasai: given the facts a lot of authors seem fine to keep it in the window bounds, I think it's reasonable <fremy> fantasai: in terms of positioning, we can punt this for now, and come back to this later <masonf> +1 to everything fantasai just said. <lea> also +1 to everything fantasai just said! <fremy> fantasai: but, globally, I think it's a net benefit if (a) it's easy (b) <missed> (c) accessibility is preserved <lea> q? <lea> q+ <miriam> q+ <nicole> q+ <fremy> lea: I would not mind the bounds restrictions to depend on the used styles <fremy> miriam: quick question <fremy> miriam: I have seen many a11y recommendations to not use the title attribute <fantasai> s/<missed>/UA handles positioning and appearance logic so it's not error-prone/ <fremy> miriam: is that an anti-pattern? <fremy> chrishtr: I have heard the same, it's often much too loud for them <fantasai> perhaps it should be less loud... <fremy> astearns: I'm wondering, can we resolve on a ::tooltip pseudo, with a few properties allowed, and figure out the details later in little pieces <lea> allowlist and window bounds are related, they should be part of the same issue <masonf> +1 <lea> +1 <fremy> astearns: any direct response to that proposed resolution? <gregwhitworth> +1 <fremy> astearns: any objection to this? <bramus> +1 <castastrophe_> Very exciting! <una> awesome :) <gregwhitworth> only 23 years <lea> 🎉 <fremy> RESOLVED: Standardize a ::tooltip pseudo, with a few properties, to style tooltips <masonf> :-) nice! |
There was one aspect that I want to re-iterate: a concern for the accessibility of the current native tooltips (the title attribute, etc.) (The only comment in this issue where this was brought up — #8930 (comment) — by @Westbrook) One of the concerns developers have when they implement custom tooltips is having to follow accessibility guidelines. The issue is that the current What I'm talking about is the WCAG “Content on Hover or Focus” — https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus.html, particularly the “Hoverable” criterion:
There is an exception:
However, if we allowed styling the tooltip, I'd argue that at this point, this exception would stop being applied. Tooltips not being hoverable (and their text not being selectable) is one of the reasons developers could continue using custom implementations. However, interestingly, there is one aspect of the
Native tooltips can be dismissed by There are no ways in CSS to achieve this. Any custom implementation would require JS to make tooltips dismissible. Though this is a rather separate issue (I'm planning to eventually open up a separate issue), I think it is worth it to bring it up here, as if the new That said, as an author, how would I want a
Until a |
I believe the prerequisite for this cool thing would be making the |
Agree, the styling side (making the native |
agree with @Westbrook and @mikemai2awesome. i think the work to make as it stands, the Two more tangential points i would like to point out. If the
|
Internet Explorer, Legacy Edge (Ledge?), and now Chromium Edge (Chomiedge?) all show(ed) The current Edge implementation also does not disappear but can be dismissed by I know this is not advancing the overall discussion, but it is worth noting one UA has tried to improve the accessibility and this proposal should not roll that back and should try to move all UAs further. |
Relevant bugs:
An a11y best practice for authors should be to not (only) use |
Instead of leaving it up to authors, what if this was automatically handled by the UA? What are the use cases where you don't want the tooltip to appear on focus? |
I hope this also brings the ability to hide browser-default tooltips. I’m currently building a custom file input by setting opacity: 0 on the native HTML file input. It has a super-annoying tooltip saying “no file chosen” which is apparently impossible to get rid of. Another example: Safari adds a tooltip to truncated text and it’s impossible to get rid of it (which has driven me crazy). |
So I filed #9447 for the allowlist. We decided not to allow customizing the content or trigger at the moment. Are there any other issues to file? Should we close this? |
Add a use case where in many pages, the range See: https://fonts.google.com/specimen/Open+Sans/tester?preview.size=131&stylecount=11 |
Unfortunately with the current design that won’t work (for native inputs), since the thumb is part of the control’s closed Shadow DOM, to which we have no access to, and it will be a while before we have control over positioning the tooltip :/ |
Now that popover and anchor positioning are moving forwards, I wonder if it’s time to re-examine standardizing tooltip styling and adding a
::tooltip
pseudo-element so that authors can customize it.History
Since 6 years have passed since then, it seems like a good time to discuss it again. Maybe this time it will bear fruit. 😁
ETA: Apparently there was also a recent Open UI discussion on this with some good discussion.
Problem statement
Default UA tooltips are generally seen as inflexible, slow, and not aesthetically pleasing. Their styling is entirely disconnected from the element they describe (e.g. observe that the font size of the span does not affect the font size of the tooltip at all), and their color scheme is set by the OS, not the page (observe how in dark mode, the tooltip is dark, even when the page is actually not).
For these reasons, nearly all popular websites employ some kind of scripting for custom tooltips. NPM packages for tooltips are in the millions of downloads per week. However, the styling employed by the vast majority of cases is actually pretty simple.
A few examples:
Literally all component libraries include a component for tooltips (OpenUI research), however due to the limitations of components, they have to create an element for something that is conceptually not an element, but a behavior of another element. This results in unpredictable markup and complex selectors (e.g. consider
<sl-tooltip>
; selectors now need to account forsl-tooltip
possibly being anywhere in the tree, consider how a selector likeul > li > ul > li
would need to be rewritten).Older scripts depend on processing all
[title]
elements on the page, renaming the attribute todata-title
or something, and adding event listeners (usually through event delegation). The downside of these scripts is that they don't work in shadow trees, and are often inaccessible.And of course, there are always the authors that will roll their own, usually also resulting in poor accessibility.
Goals
Non-goals
Proposal
We define a
::tooltip
pseudo-element and standardize the default styling through a UA rule, which could look like this:Notes:
content
property, which can be overridden to something else. Is this useful? I can see it being set to totally unrelated attributes, harming accessibility.Issues
Positioning
As it currently stands, how the tooltip is positioned is still magic. This does make it easier to implement, but makes certain common styles very difficult: how to add a pointer when you don't know how the tooltip and originating element positions relate? We definitely don't want authors to have to deal with positioning tooltips manually, as that is insanely complicated. Perhaps we should expose some info to them about the relative positions of the tooltip and element that they can use in their styling? Maybe via
env()
? Or, even better, it could be defined in terms of anchor positioning.I think it's ok if we ship an MVP where pointers are not yet possible (which still covers a large number of use cases), but the design does need to allow for this to become possible in the future. Perhaps by restricting the properties allowed in
::tooltip
Customizing display triggers
As it currently stands, what makes the tooltip to be displayed is still magic. While this is fine, especially for an MVP, it would open up a ton of really nice use cases if this was grounded in specific user action pseudo-classes that generate the tooltip or not. Authors could then generate tooltips on
:focus
,:focus-within
, via interactions on other elements (e.g.:focus + .foo::tooltip
), or even through entirely custom interactions (by toggling classes via JS).Perhaps, if we agree that setting the
content
property is what generates the box (like::before
and::after
), the default UA styles could look like this:The downside is that this couples the display trigger with the content. If someone wants to override the content, they also need to be up to date with the display triggers used and vice versa.
We could do something like this:
But this implies the box is pre-generated and simply shown, which I don't imagine is desirable for implementations.
::tooltip
in SVGInstead of using a
title
attribute, SVG supports a<title>
element, so when used in SVG,::tooltip
should cover these tooltips as well. However, there is no way to specify something analogous tocontent: attr(title)
that works with that markup pattern, which may be another reason to axe that and have the content be magic (prefixes and suffixes can always be added via::before
and::after
). Or alternatively, we can define a new keyword or function forcontent
that returns the tooltip content, regardless of where it comes from.Not exactly within the purview of the CSS WG, but it would be nice if in the future we could backport this element into HTML, to cater to the use cases that require more rich tooltip content without having to deal with all the plumbing and positioning manually. I do wonder what web compat would be like — I suspect there must be some clumsy author code out there that assumes there is only a single
<title>
element on the page, and it contains the document title. Though inline SVG would break those already.The text was updated successfully, but these errors were encountered: