From b01bb462b67ba6ef6480249767e74e5eca602175 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Mon, 4 Aug 2025 10:07:10 -0700 Subject: [PATCH] layout: Recreate lazy block size when re-doing layout to avoid floats (#38366) Block-level boxes that establish an independent formatting context need to avoid overlapping floats. If their inline size stretches, then we may need to lay out multiple times. The problem was that when trying with a different inline size, the intrinsic block size can change, but we were using the cached final block size from the previous attempt. Testing: Adding new test Fixes: #38365 Signed-off-by: Oriol Brufau --- components/layout/flow/mod.rs | 20 ++++++++------ tests/wpt/meta/MANIFEST.json | 13 ++++++++++ .../css/CSS2/floats-clear/floats-bfc-003.html | 26 +++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 tests/wpt/tests/css/CSS2/floats-clear/floats-bfc-003.html diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs index 21ae2d97085..85fdf96939e 100644 --- a/components/layout/flow/mod.rs +++ b/components/layout/flow/mod.rs @@ -1391,14 +1391,16 @@ impl IndependentFormattingContext { ) }; - let lazy_block_size = LazySize::new( - &content_box_sizes.block, - Direction::Block, - Size::FitContent, - Au::zero, - available_block_size, - is_table, - ); + let get_lazy_block_size = || { + LazySize::new( + &content_box_sizes.block, + Direction::Block, + Size::FitContent, + Au::zero, + available_block_size, + is_table, + ) + }; // The final inline size can depend on the available space, which depends on where // we are placing the box, since floats reduce the available space. @@ -1414,6 +1416,7 @@ impl IndependentFormattingContext { // compute it with an available inline space of zero. Then, after layout we can // compute the block size, and finally place among floats. let inline_size = inline_size_with_no_available_space; + let lazy_block_size = get_lazy_block_size(); layout = self.layout( layout_context, positioning_context, @@ -1479,6 +1482,7 @@ impl IndependentFormattingContext { // Later we'll check to see if the resulting block size is compatible with the // placement. let positioning_context_length = positioning_context.len(); + let lazy_block_size = get_lazy_block_size(); layout = self.layout( layout_context, positioning_context, diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 90357bd200f..b871bef05e3 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -59963,6 +59963,19 @@ {} ] ], + "floats-bfc-003.html": [ + "a40c6ae6c0e9edb2c696fc324abfa0c9eca35a91", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "floats-clear-multicol-000.html": [ "3598a2f7aba955b5ba3e6ee1739bfd468d2b28ea", [ diff --git a/tests/wpt/tests/css/CSS2/floats-clear/floats-bfc-003.html b/tests/wpt/tests/css/CSS2/floats-clear/floats-bfc-003.html new file mode 100644 index 00000000000..a40c6ae6c0e --- /dev/null +++ b/tests/wpt/tests/css/CSS2/floats-clear/floats-bfc-003.html @@ -0,0 +1,26 @@ + +CSS Test: Floats with overflow:hidden next to them + + + + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
+
+
+
+
+
+