layout: Avoid negative corner radii values for border-radius (#39571)

The `border-radius` property provides the radii for the border box. For
the curvature of the padding and content boxes, we then subtract the
border and padding sizes. However, we weren't flooring the result by
zero, which could make the background completely disappear when using
`background-clip: padding-box` or `background-clip: content-box`.

Testing: Adding 4 new tests, but 2 of them fail in both Servo and
Firefox.
Fixes: #39540

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-09-30 12:37:44 +02:00 committed by GitHub
parent 5442302f8b
commit 0c22f784bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 264 additions and 8 deletions

View file

@ -1601,20 +1601,20 @@ fn glyphs_advance_by_index(
/// Radii for the padding edge or content edge /// Radii for the padding edge or content edge
fn inner_radii(mut radii: wr::BorderRadius, insets: units::LayoutSideOffsets) -> wr::BorderRadius { fn inner_radii(mut radii: wr::BorderRadius, insets: units::LayoutSideOffsets) -> wr::BorderRadius {
assert!(insets.left >= 0.0, "left inset must not be negative"); assert!(insets.left >= 0.0, "left inset must not be negative");
radii.top_left.width -= insets.left; radii.top_left.width = (radii.top_left.width - insets.left).max(0.0);
radii.bottom_left.width -= insets.left; radii.bottom_left.width = (radii.bottom_left.width - insets.left).max(0.0);
assert!(insets.right >= 0.0, "left inset must not be negative"); assert!(insets.right >= 0.0, "left inset must not be negative");
radii.top_right.width -= insets.right; radii.top_right.width = (radii.top_right.width - insets.right).max(0.0);
radii.bottom_right.width -= insets.right; radii.bottom_right.width = (radii.bottom_right.width - insets.right).max(0.0);
assert!(insets.top >= 0.0, "top inset must not be negative"); assert!(insets.top >= 0.0, "top inset must not be negative");
radii.top_left.height -= insets.top; radii.top_left.height = (radii.top_left.height - insets.top).max(0.0);
radii.top_right.height -= insets.top; radii.top_right.height = (radii.top_right.height - insets.top).max(0.0);
assert!(insets.bottom >= 0.0, "bottom inset must not be negative"); assert!(insets.bottom >= 0.0, "bottom inset must not be negative");
radii.bottom_left.height -= insets.bottom; radii.bottom_left.height = (radii.bottom_left.height - insets.bottom).max(0.0);
radii.bottom_right.height -= insets.bottom; radii.bottom_right.height = (radii.bottom_right.height - insets.bottom).max(0.0);
radii radii
} }

View file

@ -130383,6 +130383,64 @@
{} {}
] ]
], ],
"background-clip-content-box-with-border-radius-002.html": [
"e2600c6b7b2b7c6805f17981514bf9aff48f0cab",
[
null,
[
[
"/css/css-backgrounds/reference/background-clip-content-box-with-border-radius-002-ref.html",
"=="
]
],
{
"fuzzy": [
[
null,
[
[
0,
96
],
[
0,
400
]
]
]
]
}
]
],
"background-clip-content-box-with-border-radius-003.html": [
"f2f256589580be4e3668b5c96cbe4a7299628ba1",
[
null,
[
[
"/css/css-backgrounds/reference/background-clip-content-box-with-border-radius-003-ref.html",
"=="
]
],
{
"fuzzy": [
[
null,
[
[
0,
96
],
[
0,
400
]
]
]
]
}
]
],
"background-clip-padding-box-001.html": [ "background-clip-padding-box-001.html": [
"ed2b21b14837553598fc940d6db4e939fd278e2c", "ed2b21b14837553598fc940d6db4e939fd278e2c",
[ [
@ -130396,6 +130454,64 @@
{} {}
] ]
], ],
"background-clip-padding-box-with-border-radius-002.html": [
"88b304aee00ced3878af401f762065eb1c945232",
[
null,
[
[
"/css/css-backgrounds/reference/background-clip-padding-box-with-border-radius-002-ref.html",
"=="
]
],
{
"fuzzy": [
[
null,
[
[
0,
96
],
[
0,
400
]
]
]
]
}
]
],
"background-clip-padding-box-with-border-radius-003.html": [
"a9c5c6f7e68de1eae3b15c22e23a1d0e56b018da",
[
null,
[
[
"/css/css-backgrounds/reference/background-clip-padding-box-with-border-radius-003-ref.html",
"=="
]
],
{
"fuzzy": [
[
null,
[
[
0,
96
],
[
0,
400
]
]
]
]
}
]
],
"background-clip-padding-box-with-border-radius.html": [ "background-clip-padding-box-with-border-radius.html": [
"22d7bd9d297d25206834f93c78b27d9bc3b28039", "22d7bd9d297d25206834f93c78b27d9bc3b28039",
[ [
@ -429349,6 +429465,22 @@
"dc6d9a00d53495e17f21adc8915176dd8c681e1e", "dc6d9a00d53495e17f21adc8915176dd8c681e1e",
[] []
], ],
"background-clip-content-box-with-border-radius-002-ref.html": [
"6780f8c8d57e9a0b2978c287d1afe43bb82cba9b",
[]
],
"background-clip-content-box-with-border-radius-003-ref.html": [
"3ba6af62d30a4bb75458e2f0ccc554fd200c8464",
[]
],
"background-clip-padding-box-with-border-radius-002-ref.html": [
"6780f8c8d57e9a0b2978c287d1afe43bb82cba9b",
[]
],
"background-clip-padding-box-with-border-radius-003-ref.html": [
"a3d03d4f5ee3f92938b94056fa2c7b58e3da214a",
[]
],
"background-clip-padding-box-with-border-radius-ref.html": [ "background-clip-padding-box-with-border-radius-ref.html": [
"545b80d35163b43e136d21f7584082b3b9401b38", "545b80d35163b43e136d21f7584082b3b9401b38",
[] []

View file

@ -0,0 +1,2 @@
[background-clip-content-box-with-border-radius-003.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[background-clip-padding-box-with-border-radius-003.html]
expected: FAIL

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Backgrounds and Borders Test: background-clip: content-box with border-radius</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-clip">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#corner-shaping">
<link rel="help" href="https://github.com/servo/servo/issues/39540">
<link rel="match" href="reference/background-clip-content-box-with-border-radius-002-ref.html">
<meta name="fuzzy" content="maxDifference=0-96; totalPixels=0-400">
<meta name="assert" content="Backgrounds clipped to the content box should follow the content box curve, which should be equal to the outer border radius minus the corresponding border+padding thickness.">
<div style="
width: 50px;
height: 50px;
border: 25px solid black;
border-radius: 100% 0 0 0;
background-color: black;
background-clip: content-box;
"></div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Backgrounds and Borders Test: background-clip: content-box with border-radius</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-clip">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#corner-shaping">
<link rel="help" href="https://github.com/servo/servo/issues/39540">
<link rel="match" href="reference/background-clip-content-box-with-border-radius-003-ref.html">
<meta name="fuzzy" content="maxDifference=0-96; totalPixels=0-400">
<meta name="assert" content="Backgrounds clipped to the content box should follow the content box curve, which should be equal to the outer border radius minus the corresponding border+padding thickness.">
<div style="
width: 100px;
height: 100px;
padding: 25px;
border: 25px solid transparent;
border-radius: 100% 0 0 0;
background-color: black;
background-clip: content-box;
"></div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Backgrounds and Borders Test: background-clip: padding-box with border-radius</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-clip">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#corner-shaping">
<link rel="help" href="https://github.com/servo/servo/issues/39540">
<link rel="match" href="reference/background-clip-padding-box-with-border-radius-002-ref.html">
<meta name="fuzzy" content="maxDifference=0-96; totalPixels=0-400">
<meta name="assert" content="Backgrounds clipped to the padding box should follow the padding box curve, which should be equal to the outer border radius minus the corresponding border thickness.">
<div style="
width: 20px;
height: 20px;
padding: 20px;
border: 20px solid black;
border-radius: 100% 0 0 0;
background-color: black;
background-clip: padding-box;
"></div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Backgrounds and Borders Test: background-clip: padding-box with border-radius</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#the-background-clip">
<link rel="help" href="https://www.w3.org/TR/css-backgrounds-3/#corner-shaping">
<link rel="help" href="https://github.com/servo/servo/issues/39540">
<link rel="match" href="reference/background-clip-padding-box-with-border-radius-003-ref.html">
<meta name="fuzzy" content="maxDifference=0-96; totalPixels=0-400">
<meta name="assert" content="Backgrounds clipped to the padding box should follow the padding box curve, which should be equal to the outer border radius minus the corresponding border thickness.">
<div style="
width: 50px;
height: 50px;
padding: 25px;
border: 25px solid transparent;
border-radius: 100% 0 0 0;
background-color: black;
background-clip: padding-box;
"></div>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference File</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<div style="width: 100px; height: 100px; overflow: hidden">
<div style="width: 200px; height: 200px; border-radius: 100px; background-color: black;"></div>
</div>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference File</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<div style="
width: 100px;
height: 100px;
border: 50px solid white;
border-top-left-radius: 100%;
background-color: black;
"></div>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference File</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<div style="width: 100px; height: 100px; overflow: hidden">
<div style="width: 200px; height: 200px; border-radius: 100px; background-color: black;"></div>
</div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>CSS Reference File</title>
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<div style="
width: 50px;
height: 50px;
padding: 25px;
border: 25px solid white;
border-top-left-radius: 100%;
background-color: black;
"></div>