From 7489a0349fa7eb18efeaa790ca09e81f8f30f72d Mon Sep 17 00:00:00 2001 From: Jo Steven Novaryo <65610990+stevennovaryo@users.noreply.github.com> Date: Mon, 18 Aug 2025 19:25:31 +0800 Subject: [PATCH] layout: Do not include `position:fixed` children when calculating scrollable overflow for root element (#38618) Reimplementation of: #35931 For a `FragmentTree` we define a scrollable overflow calculation that includes the overflow all of it's children `Fragments`. In practice we are using this calculation for scrolling area of the viewport and defining the root scroll frames. However, since uncontained fixed positioned element is located outside of the document and should not be scrolled, and therefore it would make no sense to include them in the calculation of its scrollable overflow as well. Testing: New and existing WPT tests Fixes: #38617 Fixes: #38182 --------- Signed-off-by: Jo Steven Novaryo --- .../layout/fragment_tree/fragment_tree.rs | 24 +++++++++++++-- tests/wpt/meta/MANIFEST.json | 7 +++++ .../clip-path/clip-path-fixed-scroll.html.ini | 2 -- ...d-positioned-initial-containing-block.html | 30 +++++++++++++++++++ 4 files changed, 58 insertions(+), 5 deletions(-) delete mode 100644 tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini create mode 100644 tests/wpt/tests/css/css-overflow/scrollable-overflow-fixed-positioned-initial-containing-block.html diff --git a/components/layout/fragment_tree/fragment_tree.rs b/components/layout/fragment_tree/fragment_tree.rs index 4b6e207fcc1..852e7f2e0bd 100644 --- a/components/layout/fragment_tree/fragment_tree.rs +++ b/components/layout/fragment_tree/fragment_tree.rs @@ -10,6 +10,7 @@ use compositing_traits::display_list::AxesScrollSensitivity; use fxhash::FxHashSet; use malloc_size_of_derive::MallocSizeOf; use style::animation::AnimationSetKey; +use style::computed_values::position::T as Position; use super::{BoxFragment, ContainingBlockManager, Fragment}; use crate::ArcRefCell; @@ -124,9 +125,26 @@ impl FragmentTree { let scrollable_overflow = self.root_fragments.iter().fold( self.initial_containing_block, |overflow, fragment| { - fragment - .calculate_scrollable_overflow_for_parent() - .union(&overflow) + // Need to calculate the overflow for each fragments within the tree + // because it is required in the next stages of reflow. + let overflow_from_fragment = + fragment.calculate_scrollable_overflow_for_parent(); + + // Scrollable overflow should be accumulated in the block that + // establishes the containing block for the element. Thus, fixed + // positioned fragments whose containing block is the initial + // containing block should not be included in overflow calculation. + // See . + if fragment + .retrieve_box_fragment() + .is_some_and(|box_fragment| { + box_fragment.borrow().style.get_box().position == Position::Fixed + }) + { + return overflow; + } + + overflow.union(&overflow_from_fragment) }, ); diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 748f67ed36e..3bf5553a43a 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -607585,6 +607585,13 @@ } ] ], + "scrollable-overflow-fixed-positioned-initial-containing-block.html": [ + "10f115a012a85230a4641a1d793c0a6df0db2e78", + [ + null, + {} + ] + ], "scrollable-overflow-float.html": [ "f75c0a66cfffdfe9872c6e472966ee3cf639eae6", [ diff --git a/tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini b/tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini deleted file mode 100644 index 7addfba3787..00000000000 --- a/tests/wpt/meta/css/css-masking/clip-path/clip-path-fixed-scroll.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[clip-path-fixed-scroll.html] - expected: FAIL diff --git a/tests/wpt/tests/css/css-overflow/scrollable-overflow-fixed-positioned-initial-containing-block.html b/tests/wpt/tests/css/css-overflow/scrollable-overflow-fixed-positioned-initial-containing-block.html new file mode 100644 index 00000000000..10f115a012a --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/scrollable-overflow-fixed-positioned-initial-containing-block.html @@ -0,0 +1,30 @@ + + + +Scrollable overflow of Document element with 'position: fixed' which has ICB as containing block + + + + + + + + + + +