layout: Fix negative outline offset (#38418)

Properly caps the minimum offset on each side as recommended by the
standards: https://drafts.csswg.org/css-ui-3/#outline-offset

Testing: Covered by WPT tests. (3 new passing!)
Fixes: #19508

---------

Signed-off-by: lumiscosity <averyrudelphe@gmail.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
lumiscosity 2025-08-01 22:43:04 +02:00 committed by GitHub
parent f70d30cf1c
commit 5e89f79abe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 13 additions and 13 deletions

View file

@ -1553,13 +1553,19 @@ impl<'a> BuilderForBoxFragment<'a> {
if width == 0.0 {
return;
}
let offset = outline
.outline_offset
.px()
.max(-self.border_rect.width() / 2.0)
.max(-self.border_rect.height() / 2.0) +
width;
let outline_rect = self.border_rect.inflate(offset, offset);
// <https://drafts.csswg.org/css-ui-3/#outline-offset>
// > Negative values must cause the outline to shrink into the border box. Both
// > the height and the width of outside of the shape drawn by the outline should
// > not become smaller than twice the computed value of the outline-width
// > property, to make sure that an outline can be rendered even with large
// > negative values. User agents should apply this constraint independently in
// > each dimension. If the outline is drawn as multiple disconnected shapes, this
// > constraint applies to each shape separately.
let offset = outline.outline_offset.px() + width;
let outline_rect = self.border_rect.inflate(
offset.max(-self.border_rect.width() / 2.0 + width),
offset.max(-self.border_rect.height() / 2.0 + width),
);
let common = builder.common_properties(outline_rect, &self.fragment.style);
let widths = SideOffsets2D::new_all_same(width);
let border_style = match outline.outline_style {

View file

@ -1,2 +0,0 @@
[negative-outline-offset.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[outline-014.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[outline-015.html]
expected: FAIL