layout: Force outside ::marker to establish a BFC

Even though we were continuing the parent BFC, we weren't updating the
SequentialLayoutState to have the correct containing block info.
That caused problem in the presence of floats.

This patch establishes an idependent BFC, which avoids the problem.
This seems reasonable since outside markers are out-of-flow-ish,
and I think it matches Blink, which implements them as inline-blocks,
so they should also establish a BFC.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-06-04 18:06:04 +02:00
parent 568d24d4e3
commit dc2745e85c
2 changed files with 10 additions and 15 deletions

View file

@ -744,9 +744,14 @@ impl BlockLevelJob<'_> {
self.propagated_data, self.propagated_data,
false, /* is_list_item */ false, /* is_list_item */
); );
// An outside ::marker must establish a BFC, and can't contain floats.
let bfc = BlockFormattingContext {
contents: block_container,
contains_floats: false,
};
ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker { ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker {
base: LayoutBoxBase::new(info.into(), info.style.clone()), base: LayoutBoxBase::new(info.into(), info.style.clone()),
block_container, bfc,
list_item_style, list_item_style,
})) }))
}, },

View file

@ -308,7 +308,7 @@ pub(crate) struct CollapsibleWithParentStartMargin(bool);
pub(crate) struct OutsideMarker { pub(crate) struct OutsideMarker {
pub list_item_style: Arc<ComputedValues>, pub list_item_style: Arc<ComputedValues>,
pub base: LayoutBoxBase, pub base: LayoutBoxBase,
pub block_container: BlockContainer, pub bfc: BlockFormattingContext,
} }
impl OutsideMarker { impl OutsideMarker {
@ -318,7 +318,7 @@ impl OutsideMarker {
constraint_space: &ConstraintSpace, constraint_space: &ConstraintSpace,
) -> InlineContentSizesResult { ) -> InlineContentSizesResult {
self.base self.base
.inline_content_sizes(layout_context, constraint_space, &self.block_container) .inline_content_sizes(layout_context, constraint_space, &self.bfc.contents)
} }
fn layout( fn layout(
@ -326,8 +326,6 @@ impl OutsideMarker {
layout_context: &LayoutContext<'_>, layout_context: &LayoutContext<'_>,
containing_block: &ContainingBlock<'_>, containing_block: &ContainingBlock<'_>,
positioning_context: &mut PositioningContext, positioning_context: &mut PositioningContext,
sequential_layout_state: Option<&mut SequentialLayoutState>,
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
) -> Fragment { ) -> Fragment {
let constraint_space = ConstraintSpace::new_for_style_and_ratio( let constraint_space = ConstraintSpace::new_for_style_and_ratio(
&self.base.style, &self.base.style,
@ -342,17 +340,11 @@ impl OutsideMarker {
style: &self.base.style, style: &self.base.style,
}; };
// A ::marker can't have a stretch size (must be auto), so this doesn't matter. let flow_layout = self.bfc.layout(
// https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing
let ignore_block_margins_for_stretch = LogicalSides1D::new(false, false);
let flow_layout = self.block_container.layout(
layout_context, layout_context,
positioning_context, positioning_context,
&containing_block_for_children, &containing_block_for_children,
sequential_layout_state, false, /* depends_on_block_constraints */
collapsible_with_parent_start_margin.unwrap_or(CollapsibleWithParentStartMargin(false)),
ignore_block_margins_for_stretch,
); );
let max_inline_size = let max_inline_size =
@ -904,8 +896,6 @@ impl BlockLevelBox {
layout_context, layout_context,
containing_block, containing_block,
positioning_context, positioning_context,
sequential_layout_state,
collapsible_with_parent_start_margin,
), ),
}; };