Closed Bug 2010481 Opened 10 months ago Closed 9 months ago

":hover" interrupts "position:sticky" when scrolling with the mousewheel

Categories

(Core :: Web Painting, defect, P2)

Firefox 147
defect

Tracking

()

RESOLVED FIXED
149 Branch
Tracking Status
firefox-esr115 --- unaffected
firefox-esr140 --- unaffected
firefox147 --- fixed
firefox148 --- fixed
firefox149 --- fixed

People

(Reporter: tgv.adn.h2o.xyz, Assigned: botond)

References

(Regression)

Details

(Keywords: nightly-community, regression)

Attachments

(1 file, 3 external files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:147.0) Gecko/20100101 Firefox/147.0

Steps to reproduce:

147.0 (64-bit), Windows 10
build ID: 20260105210555

Since updating to the latest release version, I've been experiencing an issue with sticky elements becoming temporarily frozen when that element and an element with ":hover" styles have been moused over in a specific sequence.

Use the following HTML and steps to reproduce the bug:

<html><head>
	<style>a:hover{color:#F00;}</style>
</head>
<body style="height:3000px;">
	<nav style="position:sticky;top:0;">STICKY NAV</nav>
	<a>HOVER ELEMENT</a>
</body></html>

1) Mouse over HOVER ELEMENT, then STICKY NAV, then HOVER ELEMENT, in this exact sequence.
2a) Move the cursor down so it doesn't touch either element, and scroll down using the mousewheel. The sticky element will not follow the screen until having scrolled down far enough (distance varies with viewport height).
OR
2b) Keep the cursor over HOVER ELEMENT and scroll down using the mousewheel. The sticky element will not follow the screen until scrolling has stopped (more obvious with smooth scrolling enabled).
3) After step 2a, doing any of the following will unfreeze and bring the STICKY NAV back on screen (not an exhaustive list):

  • Mousing over HOVER ELEMENT again,
  • Mousing over the scroll bar,
  • Using the arrow keys to scroll,
  • Changing focus to or from the Firefox window from or to another.

The HOVER ELEMENT can be any type of element (not just <a>), and the hover style can be anything as well (not just color). The height style added to the body is only so we're actually able to scroll down, but otherwise is of no consequence to this issue. Doesn't matter either if the ":hover" style is in a style tag or a CSS file, or whether it's applied to an element or class.

The issue persists when using a new Firefox profile. I did not test the issue on a Nightly build.

Status: UNCONFIRMED → NEW
Ever confirmed: true
Regressed by: 1730749

:botond, since you are the author of the regressor, bug 1730749, could you take a look? Also, could you set the severity field?

For more information, please visit BugBot documentation.

Flags: needinfo?(botond)

Thanks for the report! I will investigate.

Assignee: nobody → botond
Severity: -- → S3
Component: Layout: Positioned → Web Painting
Flags: needinfo?(botond)
Priority: -- → P2

It looks like this is related to retained display lists.

The bug is triggered when the following happens:

  1. We build a (Gecko) display list for painting. We correctly treat the sticky element as being "active" (shouldFlatten=false), and save that information on the StickyScrollContainer here.
  2. We build a display list for event handling. In the repro steps, this is triggered by the hover. For event handling, we don't consider scroll frames or sticky elements as being active, and we overwrite the StickyScrollContainer flag to shouldFlatten=true (same place in the code as the first step).
  3. We get a paint that reuses the display list that was built in step (1) and retained. In nsDisplayStickyPosition::CreateWebRenderCommands, we read the flag on the StickyScrollContainer which is now false, and consequently treat the sticky item as inactive in WebRender (we don't assign its stacking context a distinct spatial id).
  4. We async scroll the WebRender display list built in step (3), resulting in the sticky item incorrectly moving together with the rest of the scroll frame's contents.

Can we refactor so that we only read and write that value in retained builds? In other types of builds we compute it but don't store/read from that place?

This value is only read if we're painting to the window.

If we write false to it during a hit test, with retained display lists
the next paint to the window can incorrectly use that value.

(In reply to Timothy Nikkel (:tnikkel) from comment #6)

Can we refactor so that we only read and write that value in retained builds? In other types of builds we compute it but don't store/read from that place?

Yeah, I have a simple fix along those lines (now posted). Just need to figure out how to write a test that exercises this.

Pushed by bballo@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/1da2ae459617 https://hg.mozilla.org/integration/autoland/rev/70f2a0bbad42 Do not write to StickyScrollContainer::mShouldFlatten if we're not painting to the window. r=layout-reviewers,tnikkel
Status: NEW → RESOLVED
Closed: 9 months ago
Resolution: --- → FIXED
Target Milestone: --- → 149 Branch

The patch landed in nightly and beta is affected.
:botond, is this bug important enough to require an uplift?

For more information, please visit BugBot documentation.

Flags: needinfo?(botond)
Duplicate of this bug: 2012279

firefox-beta Uplift Approval Request

  • User impact if declined: Users can sometimes experience temporary jumps of position:sticky content (e.g. headers, sidebars) during scrolling. Affected sites include Facebook.
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Patch is small and fairly straightforward
  • String changes made/needed: none
  • Is Android affected?: no
Attachment #9540258 - Flags: approval-mozilla-beta?

This value is only read if we're painting to the window.

If we write false to it during a hit test, with retained display lists
the next paint to the window can incorrectly use that value.

Original Revision: https://phabricator.services.mozilla.com/D280348

Flags: needinfo?(botond)
Attachment #9540258 - Flags: approval-mozilla-beta? → approval-mozilla-beta+

I've seen this pop up in various Reddit threads too. Should we nominate this for dot release uplift also?

Flags: needinfo?(botond)
Flags: in-testsuite+

(In reply to Ryan VanderMeulen [:RyanVM] from comment #16)

I've seen this pop up in various Reddit threads too. Should we nominate this for dot release uplift also?

+1, given that we haven't seen any issues with this fix, and the release is still several weeks off. I've nominated it: https://phabricator.services.mozilla.com/D281131.

Flags: needinfo?(botond)

firefox-release Uplift Approval Request

  • User impact if declined: Users can sometimes experience temporary jumps of position:sticky content (e.g. headers, sidebars) during scrolling. Affected sites include Facebook and there are various reports on reddit of users noticing this.
  • Code covered by automated testing: yes
  • Fix verified in Nightly: yes
  • Needs manual QE test: no
  • Steps to reproduce for manual QE testing:
  • Risk associated with taking this patch: low
  • Explanation of risk level: Patch is small and fairly straightforward
  • String changes made/needed: none
  • Is Android affected?: no
Attachment #9541155 - Flags: approval-mozilla-release?

This value is only read if we're painting to the window.

If we write false to it during a hit test, with retained display lists
the next paint to the window can incorrectly use that value.

Original Revision: https://phabricator.services.mozilla.com/D280348

Attachment #9541155 - Flags: approval-mozilla-release? → approval-mozilla-release+
Attachment #9541155 - Attachment description: Bug 2010481 - Do not write to StickyScrollContainer::mShouldFlatten if we're not painting to the window. a=dmeehan DONTBUILD → Bug 2010481 - Do not write to StickyScrollContainer::mShouldFlatten if we're not painting to the window. a=dmeehan
Attachment #9541155 - Attachment description: Bug 2010481 - Do not write to StickyScrollContainer::mShouldFlatten if we're not painting to the window. a=dmeehan → Bug 2010481 - Do not write to StickyScrollContainer::mShouldFlatten if we're not painting to the window.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: