layout: Floor content-box size by zero when stretching flex item (#38521)

When stretching the cross size of a flex item to its flex line, we were
computing the stretch size by subtracting padding, border and margin
from the line size. However, this could result in a negative amount for
the content-box cross size. Therefore, this floors it by zero.

Testing: Adding new tests
Fixes: #38517

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-08-07 11:19:22 -07:00 committed by GitHub
parent cf99d437fb
commit 87538282db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 99 additions and 1 deletions

View file

@ -1552,7 +1552,7 @@ impl InitialFlexLineLayout<'_> {
cross_axis, cross_axis,
Size::Stretch, Size::Stretch,
Au::zero, Au::zero,
Some(final_line_cross_size - item.item.pbm_auto_is_zero.cross), Some(Au::zero().max(final_line_cross_size - item.item.pbm_auto_is_zero.cross)),
|| content_size.into(), || content_size.into(),
// Tables have a special sizing in the block axis in that handles collapsed rows, // Tables have a special sizing in the block axis in that handles collapsed rows,
// but it would prevent stretching. So we only recognize tables in the inline axis. // but it would prevent stretching. So we only recognize tables in the inline axis.

View file

@ -255316,6 +255316,32 @@
{} {}
] ]
], ],
"flexbox-stretch-minimum-001.html": [
"499a9076f3d18c693db904cee001f9896c052b45",
[
null,
[
[
"/css/reference/ref-filled-green-200px-square.html",
"=="
]
],
{}
]
],
"flexbox-stretch-minimum-002.html": [
"cfb1cd13b424d5ec1ffd5665f576eb4711bda9b9",
[
null,
[
[
"/css/reference/ref-filled-green-200px-square.html",
"=="
]
],
{}
]
],
"min-width-1.html": [ "min-width-1.html": [
"a1a39073e88d4626be7c469611e3593415849e7a", "a1a39073e88d4626be7c469611e3593415849e7a",
[ [

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Non-negative content-box size of stretched flex item with `stretch` min cross size</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing">
<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#stretched">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11076">
<link rel="help" href="https://github.com/servo/servo/issues/38517">
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
<meta assert="Stretching the cross size of a flex item to the flex line should never result
in a negative content-box size.">
<style>
#red {
position: absolute;
z-index: -1;
width: 200px;
height: 200px;
background: red;
}
#flex-container {
display: flex;
flex-direction: row;
height: 0;
}
#flex-item {
min-height: stretch;
border: 100px solid green;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="red"></div>
<div id="flex-container">
<div id="flex-item"></div>
</div>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Non-negative content-box size of stretched flex item with `stretch` min cross size</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing">
<link rel="help" href="https://drafts.csswg.org/css-flexbox-1/#stretched">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11076">
<link rel="help" href="https://github.com/servo/servo/issues/38517">
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
<meta assert="Stretching the cross size of a flex item to the flex line should never result
in a negative content-box size.">
<style>
#red {
position: absolute;
z-index: -1;
width: 200px;
height: 200px;
background: red;
}
#flex-container {
display: flex;
flex-direction: column;
width: 0;
}
#flex-item {
min-width: stretch;
border: 100px solid green;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="red"></div>
<div id="flex-container">
<div id="flex-item"></div>
</div>