From cd8b803368fd917a474af15ab71c4b622a7c6154 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Fri, 30 Aug 2024 08:28:14 +0200 Subject: [PATCH] Use the proper aspect ratio in flexbox (#33256) When computing the automatic minimum size, flex layout was using the natural aspect ratio, ignoring the `aspect-ratio` property. `ReplacedContent::inline_size_over_block_size_intrinsic_ratio()` is now made private to avoid more accidental uses. Signed-off-by: Oriol Brufau Co-authored-by: Martin Robinson --- components/layout_2020/flexbox/layout.rs | 46 ++++++++----------- components/layout_2020/replaced.rs | 2 +- tests/wpt/meta/MANIFEST.json | 13 ++++++ .../aspect-ratio/flex-aspect-ratio-055.html | 24 ++++++++++ 4 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 tests/wpt/tests/css/css-sizing/aspect-ratio/flex-aspect-ratio-055.html diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index b7dd80d31ae..5890924db67 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -9,6 +9,7 @@ use app_units::Au; use atomic_refcell::AtomicRefMut; use itertools::izip; use style::computed_values::position::T as Position; +use style::logical_geometry::Direction; use style::properties::longhands::align_items::computed_value::T as AlignItems; use style::properties::longhands::align_self::computed_value::T as AlignSelf; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; @@ -2124,38 +2125,27 @@ impl FlexItemBox { // > size suggestion is that size. It is otherwise undefined. let specified_size_suggestion = content_box_size.main.non_auto(); - let (is_replaced, main_size_over_cross_size_intrinsic_ratio) = - match self.independent_formatting_context { - IndependentFormattingContext::NonReplaced(_) => (false, None), - IndependentFormattingContext::Replaced(ref replaced) => { - let ratio = replaced - .contents - .inline_size_over_block_size_intrinsic_ratio( - self.independent_formatting_context.style(), - ) - .map(|ratio| { - if cross_axis_is_item_block_axis { - ratio - } else { - 1.0 / ratio - } - }); - (true, ratio) - }, - }; + let (is_replaced, ratio) = match self.independent_formatting_context { + IndependentFormattingContext::NonReplaced(_) => (false, None), + IndependentFormattingContext::Replaced(ref replaced) => { + (true, replaced.preferred_aspect_ratio(containing_block)) + }, + }; + let main_axis = if cross_axis_is_item_block_axis { + Direction::Inline + } else { + Direction::Block + }; // > **transferred size suggestion** // > If the item has a preferred aspect ratio and its preferred cross size is definite, then the // > transferred size suggestion is that size (clamped by its minimum and maximum cross sizes if they // > are definite), converted through the aspect ratio. It is otherwise undefined. - let transferred_size_suggestion = match ( - main_size_over_cross_size_intrinsic_ratio, - content_box_size.cross, - ) { + let transferred_size_suggestion = match (ratio, content_box_size.cross) { (Some(ratio), AuOrAuto::LengthPercentage(cross_size)) => { let cross_size = cross_size .clamp_between_extremums(min_size.cross.auto_is(Au::zero), max_size.cross); - Some(cross_size.scale_by(ratio)) + Some(ratio.compute_dependent_size(main_axis, cross_size)) }, _ => None, }; @@ -2181,11 +2171,13 @@ impl FlexItemBox { } else { block_content_size_callback(self) }; - let content_size_suggestion = main_size_over_cross_size_intrinsic_ratio + let content_size_suggestion = ratio .map(|ratio| { main_content_size.clamp_between_extremums( - min_size.cross.auto_is(Au::zero).scale_by(ratio), - max_size.cross.map(|l| l.scale_by(ratio)), + ratio.compute_dependent_size(main_axis, min_size.cross.auto_is(Au::zero)), + max_size + .cross + .map(|l| ratio.compute_dependent_size(main_axis, l)), ) }) .unwrap_or(main_content_size); diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index 4c14d42f2c6..d8a9f5d07aa 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -238,7 +238,7 @@ impl ReplacedContent { LogicalVec2::from_physical_size(&intrinsic_size, style.effective_writing_mode()) } - pub(crate) fn inline_size_over_block_size_intrinsic_ratio( + fn inline_size_over_block_size_intrinsic_ratio( &self, style: &ComputedValues, ) -> Option { diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 7891fe10149..f2842944266 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -235020,6 +235020,19 @@ {} ] ], + "flex-aspect-ratio-055.html": [ + "d512d84c866a283c5e36b61c62062bf72d2b44f4", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "floats-aspect-ratio-001.html": [ "53627d2134aacff311142d5513a5a662264143de", [ diff --git a/tests/wpt/tests/css/css-sizing/aspect-ratio/flex-aspect-ratio-055.html b/tests/wpt/tests/css/css-sizing/aspect-ratio/flex-aspect-ratio-055.html new file mode 100644 index 00000000000..d512d84c866 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/aspect-ratio/flex-aspect-ratio-055.html @@ -0,0 +1,24 @@ + + + + + + + + +

Test passes if there is a filled green square.

+
+ +