aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOriol Brufau <obrufau@igalia.com>2025-02-17 18:51:10 +0100
committerGitHub <noreply@github.com>2025-02-17 17:51:10 +0000
commitc2224d5afc470b0137e018697357b9806bb2a05f (patch)
tree1297619c8af84b6fd33b4153f31ca3a26fc2eec1
parent5fa14c97bd64f01e90389119853cb92e94b3ba3d (diff)
downloadservo-c2224d5afc470b0137e018697357b9806bb2a05f.tar.gz
servo-c2224d5afc470b0137e018697357b9806bb2a05f.zip
layout: Partial support for sizing keywords on flex items (#35469)
* Add tests for sizing keywords on flex items Signed-off-by: Oriol Brufau <obrufau@igalia.com> * layout: Partial support for sizing keywords on flex items When a flex item has `flex-basis: auto`, the used `flex-basis` is the value of the main size property. In that case, if the main size property was set to keyword, we were always assuming it was `auto`. Now we handle non-`auto` keywords correctly. Signed-off-by: Oriol Brufau <obrufau@igalia.com> --------- Signed-off-by: Oriol Brufau <obrufau@igalia.com>
-rw-r--r--components/layout_2020/flexbox/layout.rs40
-rw-r--r--components/layout_2020/style_ext.rs22
-rw-r--r--tests/wpt/meta/MANIFEST.json14
-rw-r--r--tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-001.html.ini147
-rw-r--r--tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-002.html.ini150
-rw-r--r--tests/wpt/meta/css/css-sizing/stretch/stretch-block-size-001.html.ini6
-rw-r--r--tests/wpt/meta/css/css-sizing/stretch/stretch-inline-size-001.html.ini6
-rw-r--r--tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-001.html153
-rw-r--r--tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-002.html153
9 files changed, 639 insertions, 52 deletions
diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs
index 30148a08e09..3b735dac52c 100644
--- a/components/layout_2020/flexbox/layout.rs
+++ b/components/layout_2020/flexbox/layout.rs
@@ -42,8 +42,7 @@ use crate::sizing::{
ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult, IntrinsicSizingMode,
};
use crate::style_ext::{
- AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBMDeprecated, LayoutStyle,
- PaddingBorderMargin,
+ AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, LayoutStyle, PaddingBorderMargin,
};
use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock,
@@ -1119,17 +1118,19 @@ impl<'a> FlexItem<'a> {
config.flex_axis,
);
- let ContentBoxSizesAndPBMDeprecated {
- content_box_size,
- content_min_box_size,
- content_max_box_size,
+ let ContentBoxSizesAndPBM {
+ content_box_sizes,
pbm,
depends_on_block_constraints,
} = box_
.independent_formatting_context
.layout_style()
- .content_box_sizes_and_padding_border_margin(&containing_block.into())
- .into();
+ .content_box_sizes_and_padding_border_margin(&containing_block.into());
+
+ // TODO(#32853): handle size keywords.
+ let content_box_size = content_box_sizes.map(|size| size.preferred.to_auto_or());
+ let content_min_box_size = content_box_sizes.map(|size| size.min.to_auto_or());
+ let content_max_box_size = content_box_sizes.map(|size| size.max.to_numeric());
let preferred_aspect_ratio = box_
.independent_formatting_context
@@ -1189,8 +1190,7 @@ impl<'a> FlexItem<'a> {
.container_inner_size_constraint
.map(|size| size.to_definite()),
cross_axis_is_item_block_axis,
- flex_relative_content_box_size
- .map(|size| size.non_auto().map_or(Size::Initial, Size::Numeric)),
+ flex_context.vec2_to_flex_relative(content_box_sizes.map(|size| size.preferred)),
flex_relative_content_min_size,
flex_relative_content_max_size,
preferred_aspect_ratio,
@@ -2270,17 +2270,20 @@ impl FlexItemBox {
let cross_axis_is_item_block_axis =
cross_axis_is_item_block_axis(container_is_horizontal, item_is_horizontal, flex_axis);
- let ContentBoxSizesAndPBMDeprecated {
- content_box_size,
- content_min_box_size,
- content_max_box_size,
+ let ContentBoxSizesAndPBM {
+ content_box_sizes,
pbm,
..
} = self
.independent_formatting_context
.layout_style()
- .content_box_sizes_and_padding_border_margin(containing_block)
- .into();
+ .content_box_sizes_and_padding_border_margin(containing_block);
+
+ // TODO(#32853): handle size keywords.
+ let content_box_size = content_box_sizes.map(|size| size.preferred.to_auto_or());
+ let content_min_box_size = content_box_sizes.map(|size| size.min.to_auto_or());
+ let content_max_box_size = content_box_sizes.map(|size| size.max.to_numeric());
+
let preferred_aspect_ratio = self
.independent_formatting_context
.preferred_aspect_ratio(&pbm.padding_border_sums);
@@ -2376,7 +2379,8 @@ impl FlexItemBox {
},
};
- let content_box_size = flex_axis.vec2_to_flex_relative(content_box_size);
+ let content_box_size =
+ flex_axis.vec2_to_flex_relative(content_box_sizes.map(|size| size.preferred));
let content_min_size_no_auto = flex_axis.vec2_to_flex_relative(content_min_size_no_auto);
let content_max_size = flex_axis.vec2_to_flex_relative(content_max_box_size);
@@ -2388,7 +2392,7 @@ impl FlexItemBox {
.flex_axis
.vec2_to_flex_relative(containing_block.size.map(|v| v.non_auto())),
cross_axis_is_item_block_axis,
- content_box_size.map(|size| size.non_auto().map_or(Size::Initial, Size::Numeric)),
+ content_box_size,
content_min_size_no_auto,
content_max_size,
preferred_aspect_ratio,
diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs
index fcbbd2d575b..c4a748bea18 100644
--- a/components/layout_2020/style_ext.rs
+++ b/components/layout_2020/style_ext.rs
@@ -202,28 +202,6 @@ pub(crate) struct ContentBoxSizesAndPBM {
pub depends_on_block_constraints: bool,
}
-impl From<ContentBoxSizesAndPBM> for ContentBoxSizesAndPBMDeprecated {
- fn from(sizes: ContentBoxSizesAndPBM) -> Self {
- Self {
- content_box_size: sizes
- .content_box_sizes
- .map(|size| size.preferred.to_auto_or()),
- content_min_box_size: sizes.content_box_sizes.map(|size| size.min.to_auto_or()),
- content_max_box_size: sizes.content_box_sizes.map(|size| size.max.to_numeric()),
- pbm: sizes.pbm.clone(),
- depends_on_block_constraints: sizes.depends_on_block_constraints,
- }
- }
-}
-
-pub(crate) struct ContentBoxSizesAndPBMDeprecated {
- pub content_box_size: LogicalVec2<AuOrAuto>,
- pub content_min_box_size: LogicalVec2<AuOrAuto>,
- pub content_max_box_size: LogicalVec2<Option<Au>>,
- pub pbm: PaddingBorderMargin,
- pub depends_on_block_constraints: bool,
-}
-
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct BorderStyleColor {
pub style: BorderStyle,
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 62c374060a3..de14b643290 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -592759,6 +592759,20 @@
{}
]
],
+ "keyword-sizes-on-flex-item-001.html": [
+ "5989de812e6a17bb4fa2f9ea5df634a3bfbaaccc",
+ [
+ null,
+ {}
+ ]
+ ],
+ "keyword-sizes-on-flex-item-002.html": [
+ "4a8cf76b253d2302da59c4020d370f870fa4a0c7",
+ [
+ null,
+ {}
+ ]
+ ],
"keyword-sizes-on-floated-element.html": [
"e3da8bee7eb7b613e457d00eb88a677c35698d08",
[
diff --git a/tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-001.html.ini b/tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-001.html.ini
new file mode 100644
index 00000000000..79c2bfb1d04
--- /dev/null
+++ b/tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-001.html.ini
@@ -0,0 +1,147 @@
+[keyword-sizes-on-flex-item-001.html]
+ [.test 10]
+ expected: FAIL
+
+ [.test 11]
+ expected: FAIL
+
+ [.test 12]
+ expected: FAIL
+
+ [.test 13]
+ expected: FAIL
+
+ [.test 14]
+ expected: FAIL
+
+ [.test 15]
+ expected: FAIL
+
+ [.test 16]
+ expected: FAIL
+
+ [.test 17]
+ expected: FAIL
+
+ [.test 18]
+ expected: FAIL
+
+ [.test 19]
+ expected: FAIL
+
+ [.test 20]
+ expected: FAIL
+
+ [.test 21]
+ expected: FAIL
+
+ [.test 22]
+ expected: FAIL
+
+ [.test 23]
+ expected: FAIL
+
+ [.test 24]
+ expected: FAIL
+
+ [.test 25]
+ expected: FAIL
+
+ [.test 26]
+ expected: FAIL
+
+ [.test 27]
+ expected: FAIL
+
+ [.test 28]
+ expected: FAIL
+
+ [.test 29]
+ expected: FAIL
+
+ [.test 30]
+ expected: FAIL
+
+ [.test 31]
+ expected: FAIL
+
+ [.test 32]
+ expected: FAIL
+
+ [.test 33]
+ expected: FAIL
+
+ [.test 34]
+ expected: FAIL
+
+ [.test 35]
+ expected: FAIL
+
+ [.test 36]
+ expected: FAIL
+
+ [.test 39]
+ expected: FAIL
+
+ [.test 40]
+ expected: FAIL
+
+ [.test 41]
+ expected: FAIL
+
+ [.test 42]
+ expected: FAIL
+
+ [.test 43]
+ expected: FAIL
+
+ [.test 44]
+ expected: FAIL
+
+ [.test 45]
+ expected: FAIL
+
+ [.test 49]
+ expected: FAIL
+
+ [.test 50]
+ expected: FAIL
+
+ [.test 51]
+ expected: FAIL
+
+ [.test 52]
+ expected: FAIL
+
+ [.test 53]
+ expected: FAIL
+
+ [.test 54]
+ expected: FAIL
+
+ [.test 57]
+ expected: FAIL
+
+ [.test 58]
+ expected: FAIL
+
+ [.test 59]
+ expected: FAIL
+
+ [.test 60]
+ expected: FAIL
+
+ [.test 61]
+ expected: FAIL
+
+ [.test 62]
+ expected: FAIL
+
+ [.test 63]
+ expected: FAIL
+
+ [.test 64]
+ expected: FAIL
+
+ [.test 65]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-002.html.ini b/tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-002.html.ini
new file mode 100644
index 00000000000..547bdd0ad7f
--- /dev/null
+++ b/tests/wpt/meta/css/css-sizing/keyword-sizes-on-flex-item-002.html.ini
@@ -0,0 +1,150 @@
+[keyword-sizes-on-flex-item-002.html]
+ [.test 1]
+ expected: FAIL
+
+ [.test 2]
+ expected: FAIL
+
+ [.test 3]
+ expected: FAIL
+
+ [.test 4]
+ expected: FAIL
+
+ [.test 6]
+ expected: FAIL
+
+ [.test 7]
+ expected: FAIL
+
+ [.test 8]
+ expected: FAIL
+
+ [.test 9]
+ expected: FAIL
+
+ [.test 10]
+ expected: FAIL
+
+ [.test 11]
+ expected: FAIL
+
+ [.test 12]
+ expected: FAIL
+
+ [.test 13]
+ expected: FAIL
+
+ [.test 14]
+ expected: FAIL
+
+ [.test 15]
+ expected: FAIL
+
+ [.test 16]
+ expected: FAIL
+
+ [.test 17]
+ expected: FAIL
+
+ [.test 18]
+ expected: FAIL
+
+ [.test 19]
+ expected: FAIL
+
+ [.test 20]
+ expected: FAIL
+
+ [.test 21]
+ expected: FAIL
+
+ [.test 22]
+ expected: FAIL
+
+ [.test 23]
+ expected: FAIL
+
+ [.test 24]
+ expected: FAIL
+
+ [.test 25]
+ expected: FAIL
+
+ [.test 26]
+ expected: FAIL
+
+ [.test 27]
+ expected: FAIL
+
+ [.test 31]
+ expected: FAIL
+
+ [.test 32]
+ expected: FAIL
+
+ [.test 33]
+ expected: FAIL
+
+ [.test 34]
+ expected: FAIL
+
+ [.test 35]
+ expected: FAIL
+
+ [.test 36]
+ expected: FAIL
+
+ [.test 40]
+ expected: FAIL
+
+ [.test 41]
+ expected: FAIL
+
+ [.test 42]
+ expected: FAIL
+
+ [.test 43]
+ expected: FAIL
+
+ [.test 44]
+ expected: FAIL
+
+ [.test 45]
+ expected: FAIL
+
+ [.test 49]
+ expected: FAIL
+
+ [.test 50]
+ expected: FAIL
+
+ [.test 51]
+ expected: FAIL
+
+ [.test 52]
+ expected: FAIL
+
+ [.test 53]
+ expected: FAIL
+
+ [.test 54]
+ expected: FAIL
+
+ [.test 60]
+ expected: FAIL
+
+ [.test 61]
+ expected: FAIL
+
+ [.test 62]
+ expected: FAIL
+
+ [.test 63]
+ expected: FAIL
+
+ [.test 64]
+ expected: FAIL
+
+ [.test 65]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-sizing/stretch/stretch-block-size-001.html.ini b/tests/wpt/meta/css/css-sizing/stretch/stretch-block-size-001.html.ini
index ce07e41efe1..db73de5952d 100644
--- a/tests/wpt/meta/css/css-sizing/stretch/stretch-block-size-001.html.ini
+++ b/tests/wpt/meta/css/css-sizing/stretch/stretch-block-size-001.html.ini
@@ -2,9 +2,6 @@
[[data-expected-height\] 8]
expected: FAIL
- [[data-expected-height\] 20]
- expected: FAIL
-
[[data-expected-height\] 21]
expected: FAIL
@@ -14,9 +11,6 @@
[[data-expected-height\] 31]
expected: FAIL
- [[data-expected-height\] 43]
- expected: FAIL
-
[[data-expected-height\] 44]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-sizing/stretch/stretch-inline-size-001.html.ini b/tests/wpt/meta/css/css-sizing/stretch/stretch-inline-size-001.html.ini
index 4d8f8b1ad19..c286c29b718 100644
--- a/tests/wpt/meta/css/css-sizing/stretch/stretch-inline-size-001.html.ini
+++ b/tests/wpt/meta/css/css-sizing/stretch/stretch-inline-size-001.html.ini
@@ -2,9 +2,6 @@
[[data-expected-width\] 8]
expected: FAIL
- [[data-expected-width\] 19]
- expected: FAIL
-
[[data-expected-width\] 21]
expected: FAIL
@@ -14,9 +11,6 @@
[[data-expected-width\] 31]
expected: FAIL
- [[data-expected-width\] 42]
- expected: FAIL
-
[[data-expected-width\] 44]
expected: FAIL
diff --git a/tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-001.html b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-001.html
new file mode 100644
index 00000000000..5989de812e6
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-001.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html>
+<title>Keyword sizes on flex item: row container</title>
+<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#sizing-values">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#sizing-values">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11006">
+<meta assert="The various keyword sizes work as expected on flex items.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+
+<style>
+.wrapper {
+ display: flex;
+ flex-direction: row;
+}
+.test {
+ flex: none;
+ margin: 5px;
+ border: 3px solid;
+ padding: 2px;
+ font: 20px/1 Ahem;
+}
+
+/* Set the preferred size to small amount, to test that the min size works */
+.test.min-width { width: 0px }
+.test.min-height { height: 0px }
+
+/* Set the preferred size to big amount, to test that the max size works */
+.test.max-width { width: 500px }
+.test.max-height { height: 500px }
+
+/* stretch isn't widely supported, fall back to vendor-prefixed alternatives */
+.width.stretch { width: -moz-available; width: -webkit-fill-available; width: stretch }
+.min-width.stretch { min-width: -moz-available; min-width: -webkit-fill-available; min-width: stretch }
+.max-width.stretch { max-width: -moz-available; max-width: -webkit-fill-available; max-width: stretch }
+.height.stretch { height: -moz-available; height: -webkit-fill-available; height: stretch }
+.min-height.stretch { min-height: -moz-available; min-height: -webkit-fill-available; min-height: stretch }
+.max-height.stretch { max-height: -moz-available; max-height: -webkit-fill-available; max-height: stretch }
+</style>
+<div id="log"></div>
+
+<!-- Intrinsic keywords -->
+<div class="wrapper" style="width: 100px; height: 100px">
+ <div class="test width" style="width: min-content" data-expected-width="30">X X</div>
+ <div class="test width" style="width: fit-content" data-expected-width="70">X X</div>
+ <div class="test width" style="width: max-content" data-expected-width="70">X X</div>
+
+ <div class="test width" style="width: min-content" data-expected-width="70">XXX XXX</div>
+ <div class="test width" style="width: fit-content" data-expected-width="90">XXX XXX</div>
+ <div class="test width" style="width: max-content" data-expected-width="150">XXX XXX</div>
+
+ <div class="test width" style="width: min-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test width" style="width: fit-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test width" style="width: max-content" data-expected-width="230">XXXXX XXXXX</div>
+
+ <br>
+
+ <div class="test min-width" style="min-width: min-content" data-expected-width="30">X X</div>
+ <div class="test min-width" style="min-width: fit-content" data-expected-width="70">X X</div>
+ <div class="test min-width" style="min-width: max-content" data-expected-width="70">X X</div>
+
+ <div class="test min-width" style="min-width: min-content" data-expected-width="70">XXX XXX</div>
+ <div class="test min-width" style="min-width: fit-content" data-expected-width="90">XXX XXX</div>
+ <div class="test min-width" style="min-width: max-content" data-expected-width="150">XXX XXX</div>
+
+ <div class="test min-width" style="min-width: min-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test min-width" style="min-width: fit-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test min-width" style="min-width: max-content" data-expected-width="230">XXXXX XXXXX</div>
+
+ <br>
+
+ <div class="test max-width" style="max-width: min-content" data-expected-width="30">X X</div>
+ <div class="test max-width" style="max-width: fit-content" data-expected-width="70">X X</div>
+ <div class="test max-width" style="max-width: max-content" data-expected-width="70">X X</div>
+
+ <div class="test max-width" style="max-width: min-content" data-expected-width="70">XXX XXX</div>
+ <div class="test max-width" style="max-width: fit-content" data-expected-width="90">XXX XXX</div>
+ <div class="test max-width" style="max-width: max-content" data-expected-width="150">XXX XXX</div>
+
+ <div class="test max-width" style="max-width: min-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test max-width" style="max-width: fit-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test max-width" style="max-width: max-content" data-expected-width="230">XXXXX XXXXX</div>
+
+ <br>
+
+ <div class="test height" style="height: min-content" data-expected-height="30">X X</div>
+ <div class="test height" style="height: fit-content" data-expected-height="30">X X</div>
+ <div class="test height" style="height: max-content" data-expected-height="30">X X</div>
+
+ <div class="test min-height" style="min-height: min-content" data-expected-height="30">X X</div>
+ <div class="test min-height" style="min-height: fit-content" data-expected-height="30">X X</div>
+ <div class="test min-height" style="min-height: max-content" data-expected-height="30">X X</div>
+
+ <div class="test max-height" style="max-height: min-content" data-expected-height="30">X X</div>
+ <div class="test max-height" style="max-height: fit-content" data-expected-height="30">X X</div>
+ <div class="test max-height" style="max-height: max-content" data-expected-height="30">X X</div>
+</div>
+
+<!-- Definite stretch -->
+<div class="wrapper" style="width: 100px; height: 100px">
+ <div class="test width stretch" data-expected-width="90">X X</div>
+ <div class="test width stretch" data-expected-width="90">XXX XXX</div>
+ <div class="test width stretch" data-expected-width="90">XXXXX XXXXX</div>
+
+ <div class="test min-width stretch" data-expected-width="90">X X</div>
+ <div class="test min-width stretch" data-expected-width="90">XXX XXX</div>
+ <div class="test min-width stretch" data-expected-width="90">XXXXX XXXXX</div>
+
+ <div class="test max-width stretch" data-expected-width="90">X X</div>
+ <div class="test max-width stretch" data-expected-width="90">XXX XXX</div>
+ <div class="test max-width stretch" data-expected-width="90">XXXXX XXXXX</div>
+
+ <div class="test height stretch" data-expected-height="90">X X</div>
+ <div class="test height stretch" data-expected-height="90">XXX XXX<</div>
+ <div class="test height stretch" data-expected-height="90">XXXXX XXXXX</div>
+
+ <div class="test min-height stretch" data-expected-height="90">X X</div>
+ <div class="test min-height stretch" data-expected-height="90">XXX XXX</div>
+ <div class="test min-height stretch" data-expected-height="90">XXXXX XXXXX</div>
+
+ <div class="test max-height stretch" data-expected-height="90">X X</div>
+ <div class="test max-height stretch" data-expected-height="90">XXX XXX</div>
+ <div class="test max-height stretch" data-expected-height="90">XXXXX XXXXX</div>
+</div>
+
+<!-- Stretch sizes can't result in a negative content size -->
+<div class="wrapper" style="width: 0px; height: 0px">
+ <div class="test width min-width max-width stretch" data-expected-width="10"></div>
+ <div class="test height min-height max-height stretch" data-expected-height="10"></div>
+</div>
+
+
+<!-- Indefinite stretch -->
+<div class="wrapper" style="width: 100px; max-height: 100px">
+ <div class="test height stretch indefinite" data-expected-height="30">X X</div>
+ <div class="test height stretch indefinite" data-expected-height="30">XXX XXX</div>
+ <div class="test height stretch indefinite" data-expected-height="30">XXXXX XXXXX</div>
+
+ <div class="test min-height stretch indefinite" data-expected-height="30">X X</div>
+ <div class="test min-height stretch indefinite" data-expected-height="30">XXX XXX</div>
+ <div class="test min-height stretch indefinite" data-expected-height="30">XXXXX XXXXX</div>
+
+ <div class="test max-height stretch indefinite" data-expected-height="30">X X</div>
+ <div class="test max-height stretch indefinite" data-expected-height="30">XXX XXX</div>
+ <div class="test max-height stretch indefinite" data-expected-height="30">XXXXX XXXXX</div>
+</div>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+document.fonts.ready.then(() => checkLayout(".test"));
+</script>
diff --git a/tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-002.html b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-002.html
new file mode 100644
index 00000000000..4a8cf76b253
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/keyword-sizes-on-flex-item-002.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html>
+<title>Keyword sizes on flex item: column container</title>
+<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#sizing-values">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#sizing-values">
+<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11006">
+<meta assert="The various keyword sizes work as expected on flex items.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+
+<style>
+.wrapper {
+ display: flex;
+ flex-direction: column;
+}
+.test {
+ flex: none;
+ margin: 5px;
+ border: 3px solid;
+ padding: 2px;
+ font: 20px/1 Ahem;
+}
+
+/* Set the preferred size to small amount, to test that the min size works */
+.test.min-width { width: 0px }
+.test.min-height { height: 0px }
+
+/* Set the preferred size to big amount, to test that the max size works */
+.test.max-width { width: 500px }
+.test.max-height { height: 500px }
+
+/* stretch isn't widely supported, fall back to vendor-prefixed alternatives */
+.width.stretch { width: -moz-available; width: -webkit-fill-available; width: stretch }
+.min-width.stretch { min-width: -moz-available; min-width: -webkit-fill-available; min-width: stretch }
+.max-width.stretch { max-width: -moz-available; max-width: -webkit-fill-available; max-width: stretch }
+.height.stretch { height: -moz-available; height: -webkit-fill-available; height: stretch }
+.min-height.stretch { min-height: -moz-available; min-height: -webkit-fill-available; min-height: stretch }
+.max-height.stretch { max-height: -moz-available; max-height: -webkit-fill-available; max-height: stretch }
+</style>
+<div id="log"></div>
+
+<!-- Intrinsic keywords -->
+<div class="wrapper" style="width: 100px; height: 100px">
+ <div class="test width" style="width: min-content" data-expected-width="30">X X</div>
+ <div class="test width" style="width: fit-content" data-expected-width="70">X X</div>
+ <div class="test width" style="width: max-content" data-expected-width="70">X X</div>
+
+ <div class="test width" style="width: min-content" data-expected-width="70">XXX XXX</div>
+ <div class="test width" style="width: fit-content" data-expected-width="90">XXX XXX</div>
+ <div class="test width" style="width: max-content" data-expected-width="150">XXX XXX</div>
+
+ <div class="test width" style="width: min-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test width" style="width: fit-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test width" style="width: max-content" data-expected-width="230">XXXXX XXXXX</div>
+
+ <br>
+
+ <div class="test min-width" style="min-width: min-content" data-expected-width="30">X X</div>
+ <div class="test min-width" style="min-width: fit-content" data-expected-width="70">X X</div>
+ <div class="test min-width" style="min-width: max-content" data-expected-width="70">X X</div>
+
+ <div class="test min-width" style="min-width: min-content" data-expected-width="70">XXX XXX</div>
+ <div class="test min-width" style="min-width: fit-content" data-expected-width="90">XXX XXX</div>
+ <div class="test min-width" style="min-width: max-content" data-expected-width="150">XXX XXX</div>
+
+ <div class="test min-width" style="min-width: min-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test min-width" style="min-width: fit-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test min-width" style="min-width: max-content" data-expected-width="230">XXXXX XXXXX</div>
+
+ <br>
+
+ <div class="test max-width" style="max-width: min-content" data-expected-width="30">X X</div>
+ <div class="test max-width" style="max-width: fit-content" data-expected-width="70">X X</div>
+ <div class="test max-width" style="max-width: max-content" data-expected-width="70">X X</div>
+
+ <div class="test max-width" style="max-width: min-content" data-expected-width="70">XXX XXX</div>
+ <div class="test max-width" style="max-width: fit-content" data-expected-width="90">XXX XXX</div>
+ <div class="test max-width" style="max-width: max-content" data-expected-width="150">XXX XXX</div>
+
+ <div class="test max-width" style="max-width: min-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test max-width" style="max-width: fit-content" data-expected-width="110">XXXXX XXXXX</div>
+ <div class="test max-width" style="max-width: max-content" data-expected-width="230">XXXXX XXXXX</div>
+
+ <br>
+
+ <div class="test height" style="height: min-content" data-expected-height="30">X X</div>
+ <div class="test height" style="height: fit-content" data-expected-height="30">X X</div>
+ <div class="test height" style="height: max-content" data-expected-height="30">X X</div>
+
+ <div class="test min-height" style="min-height: min-content" data-expected-height="30">X X</div>
+ <div class="test min-height" style="min-height: fit-content" data-expected-height="30">X X</div>
+ <div class="test min-height" style="min-height: max-content" data-expected-height="30">X X</div>
+
+ <div class="test max-height" style="max-height: min-content" data-expected-height="30">X X</div>
+ <div class="test max-height" style="max-height: fit-content" data-expected-height="30">X X</div>
+ <div class="test max-height" style="max-height: max-content" data-expected-height="30">X X</div>
+</div>
+
+<!-- Definite stretch -->
+<div class="wrapper" style="width: 100px; height: 100px">
+ <div class="test width stretch" data-expected-width="90">X X</div>
+ <div class="test width stretch" data-expected-width="90">XXX XXX</div>
+ <div class="test width stretch" data-expected-width="90">XXXXX XXXXX</div>
+
+ <div class="test min-width stretch" data-expected-width="90">X X</div>
+ <div class="test min-width stretch" data-expected-width="90">XXX XXX</div>
+ <div class="test min-width stretch" data-expected-width="90">XXXXX XXXXX</div>
+
+ <div class="test max-width stretch" data-expected-width="90">X X</div>
+ <div class="test max-width stretch" data-expected-width="90">XXX XXX</div>
+ <div class="test max-width stretch" data-expected-width="90">XXXXX XXXXX</div>
+
+ <div class="test height stretch" data-expected-height="90">X X</div>
+ <div class="test height stretch" data-expected-height="90">XXX XXX<</div>
+ <div class="test height stretch" data-expected-height="90">XXXXX XXXXX</div>
+
+ <div class="test min-height stretch" data-expected-height="90">X X</div>
+ <div class="test min-height stretch" data-expected-height="90">XXX XXX</div>
+ <div class="test min-height stretch" data-expected-height="90">XXXXX XXXXX</div>
+
+ <div class="test max-height stretch" data-expected-height="90">X X</div>
+ <div class="test max-height stretch" data-expected-height="90">XXX XXX</div>
+ <div class="test max-height stretch" data-expected-height="90">XXXXX XXXXX</div>
+</div>
+
+<!-- Stretch sizes can't result in a negative content size -->
+<div class="wrapper" style="width: 0px; height: 0px">
+ <div class="test width min-width max-width stretch" data-expected-width="10"></div>
+ <div class="test height min-height max-height stretch" data-expected-height="10"></div>
+</div>
+
+
+<!-- Indefinite stretch -->
+<div class="wrapper" style="width: 100px; max-height: 100px">
+ <div class="test height stretch indefinite" data-expected-height="30">X X</div>
+ <div class="test height stretch indefinite" data-expected-height="50">XXX XXX</div>
+ <div class="test height stretch indefinite" data-expected-height="50">XXXXX XXXXX</div>
+
+ <div class="test min-height stretch indefinite" data-expected-height="30">X X</div>
+ <div class="test min-height stretch indefinite" data-expected-height="50">XXX XXX</div>
+ <div class="test min-height stretch indefinite" data-expected-height="50">XXXXX XXXXX</div>
+
+ <div class="test max-height stretch indefinite" data-expected-height="30">X X</div>
+ <div class="test max-height stretch indefinite" data-expected-height="50">XXX XXX</div>
+ <div class="test max-height stretch indefinite" data-expected-height="50">XXXXX XXXXX</div>
+</div>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<script>
+document.fonts.ready.then(() => checkLayout(".test"));
+</script>