layout: Floor the max-content size by the min-content size (#36518)

It's typically a given that the min-content size can't exceed the
max-content size. However, it was possible to break that assumption when
an inline formatting context had contents with a negative outer size
(due to margins). This could lead to assert failures.

This patch avoids the problem by flooring the max-content size to not be
smaller than the min-content size. Note there is no interoperability:
https://github.com/w3c/csswg-drafts/issues/12076

Testing: adding new reftest and crashtest
Fixes: #36481

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-04-14 11:00:32 -07:00 committed by GitHub
parent 7b2fd52992
commit c7502a99f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 71 additions and 2 deletions

View file

@ -2285,10 +2285,16 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
for inline_item in inline_formatting_context.inline_items.iter() {
self.process_item(&inline_item.borrow(), inline_formatting_context);
}
self.forced_line_break();
// We might get a max-content size which is smaller than the min-content size,
// due to negative margins. So we need to adjust to avoid problems down the line.
// This is being discussed in <https://github.com/w3c/csswg-drafts/issues/12076>.
let mut sizes = self.paragraph;
sizes.max_content.max_assign(sizes.min_content);
InlineContentSizesResult {
sizes: self.paragraph,
sizes,
depends_on_block_constraints: self.depends_on_block_constraints,
}
}

View file

@ -4901,6 +4901,13 @@
{}
]
],
"cell-contents-with-negative-outer-size.html": [
"c9cd275ad9e07fa33fa4c8ac363b891562628614",
[
null,
{}
]
],
"col_span_dynamic_crash.html": [
"67630066fad440e64f901512622cbaabdc4af370",
[
@ -249543,6 +249550,19 @@
{}
]
],
"min-content-le-max-content.tentative.html": [
"81bc6969d50cd57e33b0268bc26bec6ec42ea6a9",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"min-content-min-width-000.html": [
"9dff1b973477b15b1118787e4ad5d213abfb6809",
[

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>min-content ≤ max-content</title>
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/12076">
<meta assert="The max-content size is floored to not be smaller than the min-content.">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<style>
main {
width: 100px;
height: 100px;
font-size: 0;
background: red;
}
div {
background: green
}
span {
display: inline-block;
vertical-align: top;
height: 50px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<main>
<div style="width: min-content">
<span style="width: 100px"></span>
<span style="margin-right: -50px"></span>
</div>
<div style="width: max-content">
<span style="width: 100px"></span>
<span style="margin-right: -50px"></span>
</div>
</main>

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
<link rel="help" href="https://github.com/servo/servo/issues/36481">
<style>span { display: inline-block; margin-right: -1px; }</style>
<table><td>a<span></span></td></table>