layout: Fix interaction of margin and stretch size on block-level boxes (#35904)

The CSSWG resolved that `block-size: stretch` on a block-level box
stretches the margin box to fill the parent. However, if the parent
doesn't have padding nor border, and doesn't establish an independent
formatting context, then we assume that the margins will collapse.
Therefore, we treat the margins as zero when resolving the stretch size,
regardless of whether they will actually end up collapsing.

https://github.com/w3c/csswg-drafts/issues/11044#issuecomment-2599101601
https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-03-11 22:32:28 +01:00 committed by GitHub
parent f7ddac249b
commit 9858ec81f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 379 additions and 120 deletions

View file

@ -35,8 +35,8 @@ use crate::fragment_tree::{
PositioningFragment, SpecificLayoutInfo,
};
use crate::geom::{
LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
PhysicalVec, Size, SizeConstraint, ToLogical, ToLogicalWithContainingBlock,
LogicalRect, LogicalSides, LogicalSides1D, LogicalVec2, PhysicalPoint, PhysicalRect,
PhysicalSides, PhysicalVec, Size, SizeConstraint, ToLogical, ToLogicalWithContainingBlock,
};
use crate::positioned::{PositioningContext, PositioningContextLength, relative_adjustement};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
@ -1499,6 +1499,11 @@ impl<'a> TableLayout<'a> {
style: &self.table.style,
};
// The parent of a caption is the table wrapper, which establishes an independent
// formatting context. Therefore, we don't ignore block margins when resolving a
// stretch block size. https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing
let ignore_block_margins_for_stretch = LogicalSides1D::new(false, false);
let mut box_fragment = context.layout_in_flow_block_level(
layout_context,
positioning_context
@ -1506,6 +1511,7 @@ impl<'a> TableLayout<'a> {
.unwrap_or(parent_positioning_context),
containing_block,
None, /* sequential_layout_state */
ignore_block_margins_for_stretch,
);
if let Some(mut positioning_context) = positioning_context.take() {