Skip to content

Box tree construction: only unset pseudo elements if the box is rebuilt#39930

Merged
yezhizhen merged 2 commits intoservo:mainfrom
longvatrong111:pseudo-element-incremental-layout
Oct 23, 2025
Merged

Box tree construction: only unset pseudo elements if the box is rebuilt#39930
yezhizhen merged 2 commits intoservo:mainfrom
longvatrong111:pseudo-element-incremental-layout

Conversation

@longvatrong111
Copy link
Copy Markdown
Contributor

@longvatrong111 longvatrong111 commented Oct 16, 2025

Box Tree re-construction may cause the loss of pseudo element: #39225 (comment), then causes transition stucks.
We should only unset pseudo elements if the box is rebuilt.

Testing: fix manual test in #39225, CI reports no regression: action
Fixes: #39225

cc: @xiaochengh

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Oct 16, 2025
@longvatrong111 longvatrong111 requested review from mrobinson, stevennovaryo and xiaochengh and removed request for mrobinson October 16, 2025 19:32
@jdm
Copy link
Copy Markdown
Member

jdm commented Oct 16, 2025

Can you write an automated test for this?

@longvatrong111 longvatrong111 changed the title Box tree construction: only unset pseudo elements if the box is rebuit Box tree construction: only unset pseudo elements if the box is rebuilt Oct 17, 2025
@longvatrong111 longvatrong111 force-pushed the pseudo-element-incremental-layout branch from cacab52 to 1cc1b12 Compare October 20, 2025 08:30
@servo-wpt-sync
Copy link
Copy Markdown
Collaborator

🤖 Opened new upstream WPT pull request (web-platform-tests/wpt#55540) with upstreamable changes.

@servo-wpt-sync
Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#55540).

@longvatrong111 longvatrong111 force-pushed the pseudo-element-incremental-layout branch from 1cc1b12 to a5cda0d Compare October 20, 2025 08:52
@servo-wpt-sync
Copy link
Copy Markdown
Collaborator

📝 Transplanted new upstreamable changes to existing upstream WPT pull request (web-platform-tests/wpt#55540).

Copy link
Copy Markdown
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

It should be possible to write a test without testdriver.js. We want an action that triggers reflow but not recollection, which can be done by style change.
I haven't checked this part of code for a while, what do you think? @mrobinson

@longvatrong111
Copy link
Copy Markdown
Contributor Author

longvatrong111 commented Oct 21, 2025

It should be possible to write a test without testdriver.js. We want an action that triggers reflow but not recollection, which can be done by style change. I haven't checked this part of code for a while, what do you think? @mrobinson

I also think it's better if we don't need to use testdriver. However, right now I only know this way to reproduce the issue.
We need an action that rebuilds the box tree, not re-collect children, but reuse the host box of pseudo element. Changing style would force rebuilding the box so pseudo element is re-built as well and nothing happens.

Copy link
Copy Markdown
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

https://github.com/web-platform-tests/wpt/pull/55540/checks?check_run_id=53158603955

It seems the testdriver test-case provided has very specific coordinates and only work in Servo, failing all other browsers.. I don't quite understand how is your coordinates determined.

Copy link
Copy Markdown
Contributor

@stevennovaryo stevennovaryo left a comment

Choose a reason for hiding this comment

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

I am afraid the test with Pointer might be too unstable and complex, primarily due to Webdriver implementations and difference in reflowing. We might need a to look why it is happening in the first place and more general case.

<!DOCTYPE html>
<meta charset="utf-8">
<title>::before transition keeps updating while pointer moves to another element (IntersectionObserver)</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
<link rel="help" href="https://drafts.csswg.org/css-transitions/">
<link rel="author" title="<your name>" href="mailto:<your email>@gmail.com">

Please add the contact.

<title>::before transition keeps updating while pointer moves to another element (IntersectionObserver)</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/">
<link rel="help" href="https://w3c.github.io/IntersectionObserver/">
<meta name="assert" content="Moving pointer to another element does not freeze a ::before width transition on the host; host keeps expanding until it intersects the other element.">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
<meta name="assert" content="Moving pointer to another element does not freeze a ::before width transition on the host; host keeps expanding until it intersects the other element.">
<link rel="help" href="https://github.com/servo/servo/issues/39225"/>

You could also add the issue reference.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you, I updated.

@servo-highfive servo-highfive added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Oct 21, 2025
@stevennovaryo
Copy link
Copy Markdown
Contributor

I am wondering whether we have unit tests for incremental layout. If not, whether it is plausible to introduce it or not?

@yezhizhen
Copy link
Copy Markdown
Member

yezhizhen commented Oct 21, 2025

Or, @longvatrong111 can you move the test to the folder which won't export to upstream?

This might be vulnerable to future UA stylesheet change tho..

@mrobinson
Copy link
Copy Markdown
Member

I also think it's better if we don't need to use testdriver. However, right now I only know this way to reproduce the issue. We need an action that rebuilds the box tree, not re-collect children, but reuse the host box of pseudo element. Changing style would force rebuilding the box so pseudo element is re-built as well and nothing happens.

Only certain style changes cause a rebuilding of the box tree. You can see what kind of damage style changes inflict here: https://github.com/servo/stylo/blob/main/style/servo/restyle_damage.rs#L152.

) {
element.unset_all_pseudo_boxes();
let damage = element.take_restyle_damage();
if damage.contains(LayoutDamage::recollect_box_tree_children().into()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
if damage.contains(LayoutDamage::recollect_box_tree_children().into()) {
if damage.has_box_damage() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it's reasonable.

@longvatrong111
Copy link
Copy Markdown
Contributor Author

I also think it's better if we don't need to use testdriver. However, right now I only know this way to reproduce the issue. We need an action that rebuilds the box tree, not re-collect children, but reuse the host box of pseudo element. Changing style would force rebuilding the box so pseudo element is re-built as well and nothing happens.

Only certain style changes cause a rebuilding of the box tree. You can see what kind of damage style changes inflict here: https://github.com/servo/stylo/blob/main/style/servo/restyle_damage.rs#L152.

Interesting, I tried all 4 levels of style change but still can't reproduce the issue...

@longvatrong111 longvatrong111 force-pushed the pseudo-element-incremental-layout branch from a5cda0d to 03992ad Compare October 22, 2025 07:23
@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Oct 22, 2025
@servo-wpt-sync
Copy link
Copy Markdown
Collaborator

🤖 This change no longer contains upstreamable changes to WPT; closed existing upstream pull request (web-platform-tests/wpt#55540).

@longvatrong111 longvatrong111 force-pushed the pseudo-element-incremental-layout branch 2 times, most recently from f540159 to 8a582eb Compare October 22, 2025 07:27
@longvatrong111
Copy link
Copy Markdown
Contributor Author

longvatrong111 commented Oct 22, 2025

https://github.com/web-platform-tests/wpt/pull/55540/checks?check_run_id=53158603955

It seems the testdriver test-case provided has very specific coordinates and only work in Servo, failing all other browsers.. I don't quite understand how is your coordinates determined.

I am afraid the test with Pointer might be too unstable and complex, primarily due to Webdriver implementations and difference in reflowing. We might need a to look why it is happening in the first place and more general case.

Seem like using pointer is the only way now.
The test expectation is unchanged: we expect transition to continue to regardless of other actions (unless the action implies stopping transition). The actions could be style changes or mouse move,...
So no need to worry about the correctness, the remaining task is trying to create the conditions to reproduce the issue. Using testdriver is 1 option.

Or, @longvatrong111 can you move the test to the folder which won't export to upstream?

It's reasonable.

@longvatrong111 longvatrong111 force-pushed the pseudo-element-incremental-layout branch from 8a582eb to c91c426 Compare October 22, 2025 08:05
Copy link
Copy Markdown
Member

@yezhizhen yezhizhen left a comment

Choose a reason for hiding this comment

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

I'm suspicious of the test. I feel the stylesheet is overly complicated and not minimal. But since it is only local test and not running in CI yet, it shouldn't be a big issue and we can always change later.

The fix itself is reasonable and minimal.

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Oct 23, 2025
@yezhizhen yezhizhen added this pull request to the merge queue Oct 23, 2025
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Oct 23, 2025
Merged via the queue into servo:main with commit 8132808 Oct 23, 2025
30 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Oct 23, 2025
@yezhizhen
Copy link
Copy Markdown
Member

yezhizhen commented Nov 4, 2025

@longvatrong111 It seems this test is stably failing now, but the original issue is already gone.
Can you fix the test?

@longvatrong111 longvatrong111 deleted the pseudo-element-incremental-layout branch January 9, 2026 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Quirky behavior of particular ::before pseudo element CSS transition

8 participants