Open LeaVerou opened 1 year ago
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 title
before it would be a good idea to leverage it more actively? This article isn't exactly new, but much of the ideas in it haven't gotten much attention in the interim.
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 content: attr(title)
in the user agent layer and content: initial
in the presentation hint layer.
Then it will be possible to display a tooltip on content: revert
and hide it on content: revert-layer
.
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 auto
for content
and set that as the initial value. This will either return normal
or a string in the applicable contexts set by the host language (in this case the tooltip text).
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:
Non-goals Tooltips with arbitrary HTML content (these can be done with the popover API)
Instead of using a title attribute, SVG supports a
element […] it would be nice if in the future we could backport this element into HTML
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:
<span>
, <bdi>
, and <bdo>
with different lang and dir attributes on different parts of the text<wbr>
and <br>
?<sub>
and <super>
?<ruby>
?<em>
, <strong>
, <b>
, <u>
, <i>
, <s>
, <q>
, <var>
, <code>
, <small>
, <ins>
, <del>
…?<math>
, <img>
, <svg>
…?<a>
? <button>
?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 <img>
, <svg>
, <a>
, and <button>
.… Maybe they're popovers more than tooltips, but I find the limit blurry.)
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:
the use cases that require more rich tooltip content without having to deal with all the plumbing and positioning manually
By the way, looking at #7845, the tooltip pseudo-element is somewhat similar to ::backdrop
: they seem to be present on all elements, but only displayed under certain conditions.
So it's more logical to create an auto
magic value for the display
property, apply it to those two, and to be able to hide them, put box-generation
back in the spec (#343, [CSS-DISPLAY-3] says this is deferred).
I love this and think that this is a quick win for web UI authors.
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
element on the page, and it contains the document title. Though inline SVG would break those already.
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).
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?
I'm personally in favor of V1 leaving this as magic as you noted for MVP.
Maybe via env()?
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
@tabatkins can anchor positioning help here?
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 :hover
and doesn't contain interactive content).
That doesn't mean that ::tooltip
shouldn't happen but it does introduce the need for a conditional of some form in that the UA will probably need to revert to a behavior that supports more complex styling capabilities but I'll allow the implementors to weigh in on that (eg: how hard is it to add a drop shadow to that if it's a completely different window, how do animations work, etc)?
The name And one final thing that I would like some alignment on between Open UI and the CSSWG is the naming. Tooltip has been in HTML forever so the name here makes sense, but I'm curious as look towards additional elements to add to the authors toolbox that have the semantic and a11y bindings built in leveraging the popover primitive will we use the same name given its wide adoption across the web or utilize a different name. This is lower pri, but wanted to surface this.
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:
calculate the normal
value of the content
property on ::tooltip
as none
;
add a from-markup
keyword, setting the text depending on the content of the <title>
in the SVG;
additionally add the element-text(#id)
function, which allows to take the text from the element (and this makes up for the parity of SVG with other languages);
the problem of showing the tooltip and redefining its content is solved by changing the content
value to the required via @container style(content)
and the following styles in the presentational hints and user agent layers (so the author can use the revert
to override the hiding mechanism):
/*/ 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.
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
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 :hover and doesn't contain interactive content).
I think this is a security concern. This would be troublesome if it expands the window bounds:
<a title="Your computer has been compromised, click to install antivirus" href="https://malicious.site"></a>
<style>
html, body, a { display: block; width: 100%; height: 100%; }
::tooltip {
padding: 10000px;
}
</style>
</body>
@emilio
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.
We could change the syntax to style the tooltip shared across the whole document (e.g. something like @tooltip
), and it would still cover a large chunk of use cases, but it's common to want to customize it differently per subtree and/or inherit from the element it’s on, and conceptually it makes far more sense.
I wonder if some of these mitigation strategies may make implementation more feasible:
[title], :has(>title)
elements and do away with all the designs that allow tooltips to come from entirely arbitrary attributes. content
is not initial
, and make sure to set content
on :hover
or whatever pseudo-class triggers it (this is also discussed in comment 0)::tooltip
selectors (and variatons) to style the tooltip shared across all elements, and only compute styles for elements whose tooltip is styled with more specific selectors.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.
With the current proposal, positioning is still magic, so this shouldn't be a problem for L1.
@nt1m
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 :hover and doesn't contain interactive content).
I think this is a security concern. This would be troublesome if it expands the window bounds:
<a title="Your computer has been compromised, click to install antivirus" href="https://malicious.site"></a> <style> html, body, a { display: block; width: 100%; height: 100%; } ::tooltip { padding: 10000px; } </style> </body>
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 ?)
@mfreed7
There are also the error tooltips from html5 validation
Thanks for raising this issue! So as you mentioned, OpenUI is working on a popover=hint
and Hover Triggering Proposal which is quite related. Having said that, there is a large class of use cases which likely don't need the full Popover
API, and for those, something like ::tooltip
or ::title
would do the job nicely. So I'm generally supportive.
But it's important that the developer story is clear. To me, this seems to make the most sense:
::title
/::tooltip
pseudo class is for the "common", "simple" use case of just wanting to set the basic styles for tooltips that arise due to the title
attribute. Without any data to back me up, I'd venture a guess that this will solve 80% of the tooltip use cases on the Web today.::title
/::tooltip
.If folks are roughly onboard with that split, then in my opinion, this issue (::title
/::tooltip
) should have the following goals and non-goals:
title
attribute.::title
(these should be goals for popover=hint
):title
attribute. That would be asking for a11y problems. It also has perf problems as discussed above.Regarding History: > The earliest such proposal I could find was this one from 2009. (https://lists.w3.org/Archives/Public/www-style/2009Apr/0225.html)
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:
title
attribute / <title>
SVG element?IMO:
transform-origin
).title
attribute and <title>
.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 [css-ui] Standardize tooltip styling and expose as `::tooltip`
, and agreed to the following:
RESOLVED: Standardize a ::tooltip pseudo, with a few properties, to style tooltips
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 — https://github.com/w3c/csswg-drafts/issues/8930#issuecomment-1581657010 — 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 title
tooltip does not follow these guidelines either.
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:
If pointer hover can trigger the additional content, then the pointer can be moved over the additional content without the additional content disappearing;
There is an exception:
Exception: The visual presentation of the additional content is controlled by the user agent and is not modified by the author.
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 title
tooltip that cannot in any way be currently implemented with just CSS without JS — the “Dismissible” criterion:
A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content;
Native tooltips can be dismissed by esc
.
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 ::tooltip
could be made to conform to the other criteria, it would be awesome.
That said, as an author, how would I want a ::tooltip
to behave:
::tooltip
is defined, ideally, we should remove the default UA behavior completely and add a new pseudo-element that would behave according to all the CSS rules without any additional UA behavior.esc
remove the :hover
, :focus
/:focus-visible
/a new focus-…
pseudo-class from the currently active element).title
.Until a ::tooltip
would eventually check all these boxes (I'm totally ok with things being implemented iteratively), authors would continue relying on libraries and custom implementations.
I believe the prerequisite for this cool thing would be making the title
attribute accessible first. We should not encourage devs to jump on this and create more inaccessible UIs.
Agree, the styling side (making the native title
tooltips more attractive to use) should really be accompanied by a parallel effort to make sure thy work for keyboard and assistive technology users. Making sure that browsers trigger them on focus when they're added to focusable elements (I seem to recall classic Edge did this at one point ... or was it IE11?), and providing clear guidance for authors reminding them that adding title
to arbitrary non-focusable elements will make them inaccessible to non-pointer users.
agree with @Westbrook and @mikemai2awesome. i think the work to make title
attribute accessible should be done before any work on the styling side is even started.
as it stands, the title
attribute is entirely useless not because of its inability to be styled, but because of its accessibility issues. i would hate to see ::tooltip
finalized and shipped when the accessibility discussion is still in limbo, because it would still be entirely useless.
Two more tangential points i would like to point out. If the content
property is the only way to change the tooltip text, then it would get in the way of both of these.
content: attr(aria-label)
/content: attr(aria-description)
(bypassing the title
attribute entirely), it would be severely limiting because there are better, more widely-supported ways to add labels/descriptions. using content: attr(data-tooltip)
is an option but it would cause duplication.Making sure that browsers trigger them on focus when they're added to focusable elements (I seem to recall classic Edge did this at one point ... or was it IE11?)
Internet Explorer, Legacy Edge (Ledge?), and now Chromium Edge (Chomiedge?) all show(ed) title
attributes on focus (assuming the thing with title
can take focus).
The current Edge implementation also does not disappear but can be dismissed by Esc
. Moving the mouse into the trigger does dismiss it (and re-open it) so its 1.4.13 adherence is at least better than others.
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.
Making sure that browsers trigger them on focus [...]
Internet Explorer, Legacy Edge (Ledge?), and now Chromium Edge (Chomiedge?) all show(ed) title attributes on focus (assuming the thing with title can take focus).
Relevant bugs:
An a11y best practice for authors should be to not (only) use :hover
with this new ::tooltip
pseudo-element (such as [title]:hover::tooltip
used in the examples above), or at least also include :focus
/:focus-visible
.
An a11y best practice for authors should be to not (only) use
:hover
with this new::tooltip
pseudo-element (such as[title]:hover::tooltip
used in the examples above), or at least also include:focus
/:focus-visible
.
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).
The CSS Working Group just discussed
[css-ui] Standardize tooltip styling and expose as `::tooltip`
, and agreed to the following:
RESOLVED: Standardize a ::tooltip pseudo, with a few properties, to style tooltips
The full IRC log of that discussion
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 <input>
will also have a tooltip to show the current value.
See: https://fonts.google.com/specimen/Open+Sans/tester?preview.size=131&stylecount=11
Add a use case where in many pages, the range
<input>
will also have a tooltip to show the current value.
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.