From bc58bb080f5a209f8817de7a33e33613d567c012 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Thu, 8 Jun 2023 11:55:20 +0200 Subject: [PATCH] Layout 2020: Properly handle negative block margins in floats If a float has negative block margins, it should be pushed upward, but shouldn't affect the positioning of any floats that came before it. It should lower the ceiling though when it still has some non-negative block contribution. In order to implement this behavior, we should only place the float considering its non-negative block length contribution. If the float is pushed up completely past it's "natural" position, it should be placed like a float with zero block size. --- components/layout_2020/flow/float.rs | 15 +++++++++++---- tests/wpt/metadata/MANIFEST.json | 17 +++++++++++++++++ ...oat-out-of-block-formatting-context-ref.html | 8 ++++++++ ...g-float-out-of-block-formatting-context.html | 13 +++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context-ref.html create mode 100644 tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context.html diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs index 784c5d62722..0ac6529278a 100644 --- a/components/layout_2020/flow/float.rs +++ b/components/layout_2020/flow/float.rs @@ -25,7 +25,7 @@ use std::{f32, mem}; use style::computed_values::clear::T as ClearProperty; use style::computed_values::float::T as FloatProperty; use style::properties::ComputedValues; -use style::values::computed::Length; +use style::values::computed::{CSSPixelLength, Length}; use style::values::specified::text::TextDecorationLine; /// A floating box. @@ -191,14 +191,22 @@ impl FloatContext { /// Places a new float and adds it to the list. Returns the start corner of its margin box. pub fn add_float(&mut self, new_float: &PlacementInfo) -> Vec2 { // Place the float. - let new_float_origin = self.place_object(new_float); + let new_float_origin = self.place_object(&new_float); let new_float_extent = match new_float.side { FloatSide::Left => new_float_origin.inline + new_float.size.inline, FloatSide::Right => new_float_origin.inline, }; + let new_float_rect = Rect { start_corner: new_float_origin, - size: new_float.size.clone(), + // If this float has a negative margin, we should only consider its non-negative + // block size contribution when determing where to place it. When the margin is + // so negative that it's placed completely above the current float ceiling, then + // we should position it as if it had zero block size. + size: Vec2 { + inline: new_float.size.inline.max(CSSPixelLength::zero()), + block: new_float.size.block.max(CSSPixelLength::zero()), + }, }; // Update clear. @@ -759,7 +767,6 @@ impl FloatBox { .make_fragments(&replaced.style, content_size.clone()); }, }; - let margin_box_start_corner = float_context.add_float(&PlacementInfo { size: &content_size + &pbm_sums.sum(), side: FloatSide::from_style(&style).expect("Float box wasn't floated!"), diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 8e22e1ee7e1..efebc16e140 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -60647,6 +60647,19 @@ {} ] ], + "negative-block-margin-pushing-float-out-of-block-formatting-context.html": [ + "0ebe54c1904e0c2487ebe15c4d60e9e93672d859", + [ + null, + [ + [ + "/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context-ref.html", + "==" + ] + ], + {} + ] + ], "negative-margin-float-positioning.html": [ "8b4aef22f71f8695ebbc5b6dc83ad5639945618d", [ @@ -359477,6 +359490,10 @@ "68139cdbe2d7c998b6d948f5ecca0ed7ce367694", [] ], + "negative-block-margin-pushing-float-out-of-block-formatting-context-ref.html": [ + "09a0ed094f8eb82f9fa25c4f09bb3f8a1f79c4c9", + [] + ], "overflow-scroll-float-paint-order-ref.html": [ "0fb53d4ecd3cd77e6588be0b271a2ee47950bd29", [] diff --git a/tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context-ref.html b/tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context-ref.html new file mode 100644 index 00000000000..09a0ed094f8 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context-ref.html @@ -0,0 +1,8 @@ + + + + + + +
+ diff --git a/tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context.html b/tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context.html new file mode 100644 index 00000000000..0ebe54c1904 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/CSS2/floats/negative-block-margin-pushing-float-out-of-block-formatting-context.html @@ -0,0 +1,13 @@ + + + + + + + + +
+
+
+
+