Skip to content

Conversation

foolip
Copy link
Member

@foolip foolip commented Feb 6, 2025

The interestfor attribute indicates that an element is an interest
invoker and points (via ID) at the element that should be invoked (made
visible, typically) when the user shows interest in the invoker. When
the target is a popover, it is automatically opened and closed as
interest is gained and lost. The delay before interest is gained or lost
can be customized using the interest-delay-* CSS properties.

The typical use case for this is hovercards and tooltips.

Keyboards, pointing devices, and touch behavior is normatively defined, and the
user agent should provide a way for the user to express interest regardless of
input modality.

Based on https://open-ui.org/components/interest-invokers.explainer/ and
the implementation in Chromium.

The :interest-source and :interest-target CSS pseudo-classes are defined here:
https://drafts.csswg.org/selectors/#interest-pseudos

The interest-delay-* CSS properties are defined here:
https://drafts.csswg.org/css-ui-4/#interest


(See WHATWG Working Mode: Changes for more details.)


/browsers.html ( diff )
/form-elements.html ( diff )
/image-maps.html ( diff )
/index.html ( diff )
/indices.html ( diff )
/infrastructure.html ( diff )
/interaction.html ( diff )
/popover.html ( diff )
/semantics-other.html ( diff )
/text-level-semantics.html ( diff )
/interestfor.html ( diff )

@foolip
Copy link
Member Author

foolip commented Feb 6, 2025

This is an initial translation of https://open-ui.org/components/interest-invokers.explainer/ to spec language, with a lot of things incomplete.

@mfreed7 I think the two biggest points of uncertainty I have now are the integration with mouse/keyboard/touch input on the one end, and with CSS on the other.

For showing interest, the timing of these algorithms relative to "mouseover" and other events needs to be defined.

For CSS, the fact that there are CSS properties controlling the timing means we need to think about:

  • When do we look at the computed style to extract those times?
  • Is there a state machine with timers, and is anything observable between the initial sign of interest and when we run "capture interest"?

There are many more minor TODOs, but I'd like to get the high-level flow settled first.

@foolip foolip changed the title Add the interesttarget attribute Add the interesttarget attribute Feb 6, 2025
source Outdated

<ul>
<li><p>Actually invoke the capture/lose algorithms.</p></li>
<li><p>Which algorithm reads the computed style for interest-target-delay?</p></li>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There need to be algorithms equivalent to these from Chromium code:

I think those three should hit most of the things in this list. Hopefully.

@foolip foolip force-pushed the foolip/interesttarget branch from 0aac997 to 9e40cb6 Compare May 14, 2025 14:52
source Outdated
<ul>
<li><p><dfn export for="interest state" data-x="interest-state-none">none</dfn></p></li>

<li><p><dfn export for="interest state" data-x="interest-state-partial">partial</dfn></p></li>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mfreed7 Chromium additionally has a "potential partial interest" state used for popovers:

https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/dom/element.cc;l=11060-11067;drc=743a82d08e59d803c94ee1b8564b8b11dd7b462f

Do we have to do the same in the spec? Or can we check if the target element is a popover when the scheduled task runs? The popover attribute could be removed before the task runs, so checking it ahead of time seems like it adds the need to double-check it later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you'll need this. It's used e.g. to add CSS for the "hint" text about the hotkey, and to check the conditions for moving from partial interest to full interest.

This happens when a user focuses an element that targets a popover which contains interactive content. In that situation, the popover is shown in "partial interest" mode, which renders the interactive content non-keyboard-focusable, so that they don't hijack the sequential focus navigation order. Then, hitting a keyboard hotkey, or doing other things like hovering the popover with the mouse, will upgrade it to "full interest".

Since all of the above doesn't happen if the target isn't a popover, you have to check twice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Do we also need :has-potential-partial-interest?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per other conversations, this whole thread is moot.

Copy link
Collaborator

@mfreed7 mfreed7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I went through these fairly carefully and tried to provide links to Chromium code for the missing stuff. Hopefully that makes it a lot easier for you to find the equivalent code that we're trying to spec out.

source Outdated
<p>The <dfn element-attr for="html-global"><code data-x="attr-interesttarget">interesttarget</code></dfn>
attribute on <code>a</code>, <code>area</code>, and <code>button</code> elements allows authors to
set up an invoker relationship between the triggering element and a separate target element such
as a popover. With this arrangement, when the user shows interest in the triggering element (e.g.,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that it'll pay off to define a concept for "showing interest" that you can refer to, e.g. in this sentence. That will eliminate "e.g. by hovering or focusing" wherever that appears. And another for "losing interest".

The definition of "showing interest" is loosely hovering the element with the mouse for longer than the delay, or focusing the element with the keyboard for longer than the delay, or long-pressing the element on a touchscreen. Whether it makes sense to define these in words, or just rely on the algorithms that practically say those same things, I leave to you. My preference would be to leave it to the algorithms.

Current Chromium code defines this cleanly in one spot, but as of the time of this comment, the code search cache hasn't updated to see it yet. But you can see the algorithms that essentially define interest for at least mouse and keyboard here.

@foolip foolip changed the title Add the interesttarget attribute Add the interestfor attribute Jul 1, 2025
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Sep 3, 2025
This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
aarongable pushed a commit to chromium/chromium that referenced this pull request Sep 3, 2025
This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Commit-Queue: Mason Freed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1510373}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Sep 3, 2025
This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Commit-Queue: Mason Freed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1510373}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Sep 3, 2025
This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Commit-Queue: Mason Freed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1510373}
@foolip foolip removed the agenda+ To be discussed at a triage meeting label Sep 4, 2025
@foolip
Copy link
Member Author

foolip commented Sep 4, 2025

For anyone following only this PR and not the tracking issue, see #10309 (comment) about today's WHATNOT discussion and request to advance to stage 2.

lando-prod-mozilla bot pushed a commit to mozilla-firefox/firefox that referenced this pull request Sep 8, 2025
…hat have interest, a=testonly

Automatic update from web-platform-tests
Make ESC lose interest in all elements that have interest

This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Commit-Queue: Mason Freed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1510373}

--

wpt-commits: d2c3a6825856a39ca05b811576676c4488ccf3e1
wpt-pr: 54668
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Sep 9, 2025
…hat have interest, a=testonly

Automatic update from web-platform-tests
Make ESC lose interest in all elements that have interest

This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <jarharchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Commit-Queue: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1510373}

--

wpt-commits: d2c3a6825856a39ca05b811576676c4488ccf3e1
wpt-pr: 54668

UltraBlame original commit: f1521afeb3e135fd1851d48adc6d81832028011b
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Sep 9, 2025
…hat have interest, a=testonly

Automatic update from web-platform-tests
Make ESC lose interest in all elements that have interest

This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <jarharchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Commit-Queue: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1510373}

--

wpt-commits: d2c3a6825856a39ca05b811576676c4488ccf3e1
wpt-pr: 54668

UltraBlame original commit: f1521afeb3e135fd1851d48adc6d81832028011b
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Sep 9, 2025
…hat have interest, a=testonly

Automatic update from web-platform-tests
Make ESC lose interest in all elements that have interest

This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <jarharchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Commit-Queue: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1510373}

--

wpt-commits: d2c3a6825856a39ca05b811576676c4488ccf3e1
wpt-pr: 54668

UltraBlame original commit: f1521afeb3e135fd1851d48adc6d81832028011b
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this pull request Sep 9, 2025
…hat have interest, a=testonly

Automatic update from web-platform-tests
Make ESC lose interest in all elements that have interest

This CL implements the behavior described in the spec PR:

whatwg/html#11006

That is: the ESC key is handled very much like popovers - the
focus doesn't need to be on the invoker for ESC to work. Also,
hitting ESC loses interest in all elements that currently
have interest, in reverse order. A test is added to confirm this.

Note: I purposely did not use close watcher here, since I don't
believe the close watcher stack should get involved. E.g. the
android Back button should just navigate back, and not first lose
interest in things. Closing a popover or modal dialog is different
than a tooltip being open on a page.

Bug: 326681249
Change-Id: I33cc2742a677f330d90b83c29b18b22bf49b716e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6900679
Reviewed-by: Joey Arhar <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Commit-Queue: Mason Freed <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1510373}

--

wpt-commits: d2c3a6825856a39ca05b811576676c4488ccf3e1
wpt-pr: 54668
Copy link
Collaborator

@mfreed7 mfreed7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, other than the flat tree comment you made.

@foolip foolip force-pushed the foolip/interesttarget branch from b5a12a7 to fa121b6 Compare October 1, 2025 11:57
@foolip
Copy link
Member Author

foolip commented Oct 1, 2025

fa121b6 is intended to align with https://chromium-review.googlesource.com/c/chromium/src/+/6970966. @mfreed7 can you carefully review it?

It's now closer to the Chromium implementation in that it doesn't depend on a recursive call to "handle interest change", but there are differences that I'm unsure about:

  • I never cancel pending gain interest tasks, because I couldn't understand what effect it could have. All of the active interest sources already have interest (already "showing") and even if there are pending gain interest tasks, they will end up being no-ops, right?
  • If I'm reading the Chromium code right, the iteration of AllSourceInterestInvokers() comes after a check that the element is an a, area, or button element. In the spec I'm iterating "recursive active interest sources" before the same check. I can't see what else would prevent a popover from closing when moving focus or hovering from the interest source to something inside the target popover, in the simplest case just a <div> with some text.

@mfreed7
Copy link
Collaborator

mfreed7 commented Oct 3, 2025

fa121b6 is intended to align with https://chromium-review.googlesource.com/c/chromium/src/+/6970966. @mfreed7 can you carefully review it?

Thank you!

It's now closer to the Chromium implementation in that it doesn't depend on a recursive call to "handle interest change", but there are differences that I'm unsure about:

  • I never cancel pending gain interest tasks, because I couldn't understand what effect it could have. All of the active interest sources already have interest (already "showing") and even if there are pending gain interest tasks, they will end up being no-ops, right?

This seems right. I removed that code from Chromium and the tests still pass. I'll land that change, but this seems ok as-is in spec.

  • If I'm reading the Chromium code right, the iteration of AllSourceInterestInvokers() comes after a check that the element is an a, area, or button element. In the spec I'm iterating "recursive active interest sources" before the same check. I can't see what else would prevent a popover from closing when moving focus or hovering from the interest source to something inside the target popover, in the simplest case just a <div> with some text.

Hmm, HandleInterestForHoverOrFocus() is the only one that calls AllSourceInterestInvokers(), but that can be called on any element, particularly targets of interest invokers, and contents of both invokers and targets. So it can get called on elements that aren't an a, button, etc. I just stuck a comment on the change, here, that outlines the problems that I can see. I wonder if it's worth trying to bring the spec closer to the implementation of HandleInterestForHoverOrFocus()?

aarongable pushed a commit to chromium/chromium that referenced this pull request Oct 6, 2025
From the spec PR review here:

- whatwg/html#11006

it became clear that this code was over-complicated. This
simplifies it quite a bit, and retains the existing
functionality.

Bug: 326681249
Change-Id: Ie7027b9fdefd7fbf77e9d57aca89775902cc8ce6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7008933
Commit-Queue: Joey Arhar <[email protected]>
Auto-Submit: Mason Freed <[email protected]>
Reviewed-by: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1525802}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants