Skip to content

Fix child disappearing with mixed overflow clip/visible.#43620

Merged
Loirooriol merged 4 commits into
servo:mainfrom
Messi002:issue-43599
Apr 1, 2026
Merged

Fix child disappearing with mixed overflow clip/visible.#43620
Loirooriol merged 4 commits into
servo:mainfrom
Messi002:issue-43599

Conversation

@Messi002
Copy link
Copy Markdown
Contributor

@Messi002 Messi002 commented Mar 24, 2026

Fix child element disappearing when parent has mixed overflow clip/visible

When a parent element clips overflow on one axis but not the other (e.g. overflow-y: clip with overflow-x: visible), the non-clipped axis was using f32::MIN/f32::MAX. On screens with a device pixel ratio above 1, this causes child elements to disappear.

The fix uses LayoutRect::max_rect() instead.

Testing: Reproduced the bug using --device-pixel-ratio 2 on Linux and the child disappears on main branch but renders correctly with this fix.

fixes: #43599

@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Mar 24, 2026
@Loirooriol
Copy link
Copy Markdown
Contributor

Can you link the relevant WebRender logic?

@Messi002
Copy link
Copy Markdown
Contributor Author

Messi002 commented Mar 24, 2026

Hello @Loirooriol

Please find it attached here

https://github.com/servo/webrender/blob/main/webrender/src/util.rs

pub trait MaxRect {
    fn max_rect() -> Self;
}

impl MaxRect for DeviceIntRect {
    fn max_rect() -> Self {
        DeviceIntRect::from_origin_and_size(
            DeviceIntPoint::new(i32::MIN / 2, i32::MIN / 2),
            DeviceIntSize::new(i32::MAX, i32::MAX),
        )
    }
}
impl<U> MaxRect for Rect<f32, U> {
    fn max_rect() -> Self {
        // Having an unlimited bounding box is fine up until we try
        // to cast it to `i32`, where we get `-2147483648` for any
        // values larger than or equal to 2^31.
        //
        // Note: clamping to i32::MIN and i32::MAX is not a solution,
        // with explanation left as an exercise for the reader.
        const MAX_COORD: f32 = 1.0e9;

        Rect::new(
            Point2D::new(-MAX_COORD, -MAX_COORD),
            Size2D::new(2.0 * MAX_COORD, 2.0 * MAX_COORD),
        )
    }
}
impl<U> MaxRect for Box2D<f32, U> {
    fn max_rect() -> Self {
        // Having an unlimited bounding box is fine up until we try
        // to cast it to `i32`, where we get `-2147483648` for any
        // values larger than or equal to 2^31.
        //
        // Note: clamping to i32::MIN and i32::MAX is not a solution,
        // with explanation left as an exercise for the reader.
        const MAX_COORD: f32 = 1.0e9;

        Box2D::new(
            Point2D::new(-MAX_COORD, -MAX_COORD),
            Point2D::new(MAX_COORD, MAX_COORD),
        )
    }
}

@Messi002
Copy link
Copy Markdown
Contributor Author

@Loirooriol Please let me know if I'm missing something

@Loirooriol
Copy link
Copy Markdown
Contributor

I can't reproduce the problem in the issue.

   // Having an unlimited bounding box is fine up until we try
   // to cast it to `i32`

Is it cast to i32?

Instead of hardcoding const MAX_COORD: f32 = 1.0e9 in Servo too, I would use Box2D::max_rect()

@stevennovaryo
Copy link
Copy Markdown
Member

@Messi002, can you confirm whether the issue is reproductible in your side?

Also following Oriol's suggestion, please use max_rect defined by WebRender if it is possible.

For the PR description, we could use prefix fixes: to mention the issue, so that CI could automatically close the issue when it is merged.

@Loirooriol
Copy link
Copy Markdown
Contributor

The problem is that WebRender then does max - min

Can you point where this happens for Windows, but not for Linux? The difference in behavior seems a bit weird.

@Messi002
Copy link
Copy Markdown
Contributor Author

@stevennovaryo
Yes, I can reproduce it. It happens when the device pixel ratio is above 1 (as @Loirooriol found). On my Linux machine with --device-pixel-ratio 1 it looks fine, but with --device-pixel-ratio 2 the child disappears. I've updated the code to use LayoutRect::max_rect() as suggested. I'll also update the PR description.

@Messi002
Copy link
Copy Markdown
Contributor Author

@Loirooriol
I was able to reproduce it on Linux using --device-pixel-ratio 2, so it's not a Windows-only issue

@Messi002
Copy link
Copy Markdown
Contributor Author

@Loirooriol @mrobinson

Waiting for updates from you

@servo-wpt-sync
Copy link
Copy Markdown
Collaborator

🛠 These changes could not be applied onto the latest upstream WPT. Servo's copy of the Web Platform Tests may be out of sync.

@Loirooriol
Copy link
Copy Markdown
Contributor

Loirooriol commented Mar 26, 2026

Please use Fixes: #43599 in the description, as Steven said.

@Messi002
Copy link
Copy Markdown
Contributor Author

Messi002 commented Mar 26, 2026

Ok!
Thank you for the highglight @Loirooriol

@servo-wpt-sync
Copy link
Copy Markdown
Collaborator

🛠 These changes could not be applied onto the latest upstream WPT. Servo's copy of the Web Platform Tests may be out of sync.

Copy link
Copy Markdown
Contributor

@Loirooriol Loirooriol left a comment

Choose a reason for hiding this comment

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

A bit unfortunate that we can't add an automated test (#43696)

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Apr 1, 2026
@Loirooriol Loirooriol added this pull request to the merge queue Apr 1, 2026
@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 Apr 1, 2026
Merged via the queue into servo:main with commit ce61f2e Apr 1, 2026
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 Apr 1, 2026
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.

layout: Child element is missing if we have overflow clip in one axis and visible in other axis

5 participants