Fix various issues with replaced elements in flex layout (#33263)

In particular, this takes into account that flex items may be stretched,
and if they have an aspect ratio, we ma6y need to convert the stretched
size through the ratio.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Oriol Brufau 2024-08-31 01:39:18 +02:00 committed by GitHub
parent 4ae2610c24
commit 3acc9edd82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 334 additions and 481 deletions

View file

@ -14,6 +14,7 @@ use style::properties::longhands::align_items::computed_value::T as AlignItems;
use style::properties::longhands::align_self::computed_value::T as AlignSelf; use style::properties::longhands::align_self::computed_value::T as AlignSelf;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap; use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
use style::properties::ComputedValues;
use style::values::computed::length::Size; use style::values::computed::length::Size;
use style::values::computed::Length; use style::values::computed::Length;
use style::values::generics::flex::GenericFlexBasis as FlexBasis; use style::values::generics::flex::GenericFlexBasis as FlexBasis;
@ -21,9 +22,7 @@ use style::values::generics::length::{GenericLengthPercentageOrAuto, LengthPerce
use style::values::specified::align::AlignFlags; use style::values::specified::align::AlignFlags;
use style::Zero; use style::Zero;
use super::geom::{ use super::geom::{FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec2};
FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec2, MainStartCrossStart,
};
use super::{FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox}; use super::{FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox};
use crate::cell::ArcRefCell; use crate::cell::ArcRefCell;
use crate::context::LayoutContext; use crate::context::LayoutContext;
@ -244,6 +243,32 @@ struct FinalFlexLineLayout {
all_baselines: Baselines, all_baselines: Baselines,
} }
impl FlexContainerConfig {
fn align_for(&self, align_self: AlignSelf) -> AlignItems {
let value = align_self.0 .0.value();
let mapped_value = match value {
AlignFlags::AUTO | AlignFlags::NORMAL => self.align_items.0,
_ => value,
};
AlignItems(mapped_value)
}
/// Whether an item with an `auto` preferred cross size needs to be stretched
/// to fill the flex container.
/// <https://drafts.csswg.org/css-flexbox/#stretched>
fn item_with_auto_cross_size_stretches_to_container_size(
&self,
item_style: &ComputedValues,
item_margin: &FlexRelativeSides<AuOrAuto>,
) -> bool {
self.container_is_single_line &&
item_with_auto_cross_size_stretches_to_line_size(
self.align_for(item_style.clone_align_self()),
item_margin,
)
}
}
impl FlexContext<'_> { impl FlexContext<'_> {
fn vec2_to_flex_relative<T>(&self, x: LogicalVec2<T>) -> FlexRelativeVec2<T> { fn vec2_to_flex_relative<T>(&self, x: LogicalVec2<T>) -> FlexRelativeVec2<T> {
self.config.flex_axis.vec2_to_flex_relative(x) self.config.flex_axis.vec2_to_flex_relative(x)
@ -275,12 +300,7 @@ impl FlexContext<'_> {
} }
fn align_for(&self, align_self: AlignSelf) -> AlignItems { fn align_for(&self, align_self: AlignSelf) -> AlignItems {
let value = align_self.0 .0.value(); self.config.align_for(align_self)
let mapped_value = match value {
AlignFlags::AUTO | AlignFlags::NORMAL => self.config.align_items.0,
_ => value,
};
AlignItems(mapped_value)
} }
} }
@ -388,8 +408,7 @@ impl FlexContainer {
layout_context, layout_context,
containing_block_for_children, containing_block_for_children,
container_is_horizontal, container_is_horizontal,
self.config.flex_axis, &self.config,
self.config.main_start_cross_start_sides_are,
&flex_context_getter, &flex_context_getter,
); );
@ -950,6 +969,20 @@ impl<'a> FlexItem<'a> {
.content_min_box_size(containing_block, &pbm) .content_min_box_size(containing_block, &pbm)
.map(|v| v.map(Au::from)); .map(|v| v.map(Au::from));
let margin_auto_is_zero = flex_context.sides_to_flex_relative(pbm.margin.auto_is(Au::zero));
let padding = flex_context.sides_to_flex_relative(pbm.padding);
let border = flex_context.sides_to_flex_relative(pbm.border);
let margin = flex_context.sides_to_flex_relative(pbm.margin);
let padding_border = padding.sum_by_axis() + border.sum_by_axis();
let pbm_auto_is_zero = FlexRelativeVec2 {
main: padding_border.main,
cross: padding_border.cross,
} + margin_auto_is_zero.sum_by_axis();
let item_with_auto_cross_size_stretches_to_container_size = flex_context
.config
.item_with_auto_cross_size_stretches_to_container_size(&box_.style(), &margin);
let flex_relative_content_box_size = flex_context.vec2_to_flex_relative(content_box_size); let flex_relative_content_box_size = flex_context.vec2_to_flex_relative(content_box_size);
let flex_relative_content_max_size = flex_context.vec2_to_flex_relative(max_size); let flex_relative_content_max_size = flex_context.vec2_to_flex_relative(max_size);
let flex_relative_content_min_size = flex_context.vec2_to_flex_relative(min_size); let flex_relative_content_min_size = flex_context.vec2_to_flex_relative(min_size);
@ -962,6 +995,8 @@ impl<'a> FlexItem<'a> {
flex_relative_content_box_size, flex_relative_content_box_size,
flex_relative_content_min_size, flex_relative_content_min_size,
flex_relative_content_max_size, flex_relative_content_max_size,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
|item| { |item| {
let min_size_auto_is_zero = min_size.auto_is(Au::zero); let min_size_auto_is_zero = min_size.auto_is(Au::zero);
@ -971,6 +1006,7 @@ impl<'a> FlexItem<'a> {
content_box_size, content_box_size,
min_size_auto_is_zero, min_size_auto_is_zero,
max_size, max_size,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size, IntrinsicSizingMode::Size,
) )
}, },
@ -979,15 +1015,6 @@ impl<'a> FlexItem<'a> {
cross: flex_relative_content_min_size.cross.auto_is(Au::zero), cross: flex_relative_content_min_size.cross.auto_is(Au::zero),
}; };
let margin_auto_is_zero = flex_context.sides_to_flex_relative(pbm.margin.auto_is(Au::zero));
let padding = flex_context.sides_to_flex_relative(pbm.padding);
let border = flex_context.sides_to_flex_relative(pbm.border);
let padding_border = padding.sum_by_axis() + border.sum_by_axis();
let pbm_auto_is_zero = FlexRelativeVec2 {
main: padding_border.main,
cross: padding_border.cross,
} + margin_auto_is_zero.sum_by_axis();
let align_self = flex_context.align_for(box_.style().clone_align_self()); let align_self = flex_context.align_for(box_.style().clone_align_self());
let (flex_base_size, flex_base_size_is_definite) = box_.flex_base_size( let (flex_base_size, flex_base_size_is_definite) = box_.flex_base_size(
@ -999,6 +1026,8 @@ impl<'a> FlexItem<'a> {
flex_relative_content_min_size, flex_relative_content_min_size,
flex_relative_content_max_size, flex_relative_content_max_size,
padding_border, padding_border,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
|item| { |item| {
let min_size = flex_context let min_size = flex_context
.config .config
@ -1010,6 +1039,7 @@ impl<'a> FlexItem<'a> {
content_box_size, content_box_size,
min_size, min_size,
max_size, max_size,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size, IntrinsicSizingMode::Size,
) )
}, },
@ -1036,6 +1066,11 @@ impl<'a> FlexItem<'a> {
align_self, align_self,
} }
} }
fn stretches(&self) -> bool {
self.content_box_size.cross.is_auto() &&
item_with_auto_cross_size_stretches_to_line_size(self.align_self, &self.margin)
}
} }
fn cross_axis_is_item_block_axis( fn cross_axis_is_item_block_axis(
@ -1049,6 +1084,17 @@ fn cross_axis_is_item_block_axis(
container_is_row ^ item_is_orthogonal container_is_row ^ item_is_orthogonal
} }
/// Whether an item with an `auto` preferred cross size will stretched to fill the cross size of its flex line.
/// <https://drafts.csswg.org/css-flexbox/#stretched>
fn item_with_auto_cross_size_stretches_to_line_size(
align_self: AlignItems,
margin: &FlexRelativeSides<AuOrAuto>,
) -> bool {
align_self.0.value() == AlignFlags::STRETCH &&
!margin.cross_start.is_auto() &&
!margin.cross_end.is_auto()
}
// “Collect flex items into flex lines” // “Collect flex items into flex lines”
// https://drafts.csswg.org/css-flexbox/#algo-line-break // https://drafts.csswg.org/css-flexbox/#algo-line-break
fn do_initial_flex_line_layout<'items>( fn do_initial_flex_line_layout<'items>(
@ -1411,11 +1457,8 @@ impl InitialFlexLineLayout<'_> {
self.item_layout_results.iter_mut(), self.item_layout_results.iter_mut(),
self.item_used_main_sizes.iter(), self.item_used_main_sizes.iter(),
) { ) {
let has_stretch = item.align_self.0.value() == AlignFlags::STRETCH; let stretches = item.stretches();
let used_cross_size = if has_stretch && let used_cross_size = if stretches {
item.content_box_size.cross.is_auto() &&
!(item.margin.cross_start.is_auto() || item.margin.cross_end.is_auto())
{
(final_line_cross_size - item.pbm_auto_is_zero.cross).clamp_between_extremums( (final_line_cross_size - item.pbm_auto_is_zero.cross).clamp_between_extremums(
item.content_min_size.cross, item.content_min_size.cross,
item.content_max_size.cross, item.content_max_size.cross,
@ -1425,7 +1468,7 @@ impl InitialFlexLineLayout<'_> {
}; };
item_used_cross_sizes.push(used_cross_size); item_used_cross_sizes.push(used_cross_size);
if has_stretch { if stretches {
// “If the flex item has `align-self: stretch`, redo layout for its contents, // “If the flex item has `align-self: stretch`, redo layout for its contents,
// treating this used size as its definite cross size // treating this used size as its definite cross size
// so that percentage-sized children can be resolved.” // so that percentage-sized children can be resolved.”
@ -1585,7 +1628,7 @@ impl FlexItem<'_> {
flex_context: &FlexContext, flex_context: &FlexContext,
used_cross_size_override: Option<Au>, used_cross_size_override: Option<Au>,
) -> FlexItemLayoutResult { ) -> FlexItemLayoutResult {
let containing_block = &flex_context.containing_block; let containing_block = flex_context.containing_block;
let mut positioning_context = PositioningContext::new_for_style(self.box_.style()) let mut positioning_context = PositioningContext::new_for_style(self.box_.style())
.unwrap_or_else(|| { .unwrap_or_else(|| {
PositioningContext::new_for_subtree( PositioningContext::new_for_subtree(
@ -1604,24 +1647,83 @@ impl FlexItem<'_> {
); );
// … and also the items inline axis. // … and also the items inline axis.
let cross_size = match used_cross_size_override {
Some(s) => AuOrAuto::LengthPercentage(s),
None => self.content_box_size.cross.map(|cross_size| {
cross_size.clamp_between_extremums(
self.content_min_size.cross,
self.content_max_size.cross,
)
}),
};
let ifc = &mut self.box_.independent_formatting_context;
let item_writing_mode = ifc.style().effective_writing_mode();
let item_is_horizontal = item_writing_mode.is_horizontal();
let flex_axis = flex_context.config.flex_axis; let flex_axis = flex_context.config.flex_axis;
match &mut self.box_.independent_formatting_context { let cross_axis_is_item_block_axis = cross_axis_is_item_block_axis(
containing_block
.style
.effective_writing_mode()
.is_horizontal(),
item_is_horizontal,
flex_axis,
);
let (inline_size, block_size) = if cross_axis_is_item_block_axis {
(used_main_size, cross_size)
} else {
(
cross_size.auto_is(|| {
let style = ifc.style().clone();
let containing_block_for_children =
IndefiniteContainingBlock::new_for_style_and_block_size(
&style,
AuOrAuto::LengthPercentage(used_main_size),
);
let content_contributions = ifc
.inline_content_sizes(
flex_context.layout_context,
&containing_block_for_children,
&containing_block.into(),
)
.map(|size| {
size.clamp_between_extremums(
self.content_min_size.cross,
self.content_max_size.cross,
)
});
(containing_block.inline_size - self.pbm_auto_is_zero.cross)
.min(content_contributions.max_content)
.max(content_contributions.min_content)
}),
// The main size of a flex item is considered to be definite if its flex basis is definite
// or the flex container has a definite main size.
// <https://drafts.csswg.org/css-flexbox-1/#definite-sizes>
if self.flex_base_size_is_definite ||
flex_context.container_definite_inner_size.main.is_some()
{
AuOrAuto::LengthPercentage(used_main_size)
} else {
AuOrAuto::Auto
},
)
};
match ifc {
IndependentFormattingContext::Replaced(replaced) => { IndependentFormattingContext::Replaced(replaced) => {
let pbm = replaced.style.padding_border_margin(containing_block); let size = replaced
let box_size = used_cross_size_override.map(|size| LogicalVec2 { .contents
inline: replaced .used_size_as_if_inline_element_from_content_box_sizes(
.style containing_block,
.content_box_size(containing_block, &pbm) &replaced.style,
.inline LogicalVec2 {
.map(Au::from), inline: AuOrAuto::LengthPercentage(inline_size),
block: AuOrAuto::LengthPercentage(size), block: block_size,
}); },
let size = replaced.contents.used_size_as_if_inline_element( flex_axis.vec2_to_flow_relative(self.content_min_size),
containing_block, flex_axis.vec2_to_flow_relative(self.content_max_size),
&replaced.style, );
box_size,
&pbm,
);
let cross_size = flex_axis.vec2_to_flex_relative(size).cross; let cross_size = flex_axis.vec2_to_flex_relative(size).cross;
let fragments = replaced.contents.make_fragments( let fragments = replaced.contents.make_fragments(
&replaced.style, &replaced.style,
@ -1640,66 +1742,6 @@ impl FlexItem<'_> {
} }
}, },
IndependentFormattingContext::NonReplaced(non_replaced) => { IndependentFormattingContext::NonReplaced(non_replaced) => {
let cross_size = match used_cross_size_override {
Some(s) => AuOrAuto::LengthPercentage(s),
None => self.content_box_size.cross.map(|cross_size| {
cross_size.clamp_between_extremums(
self.content_min_size.cross,
self.content_max_size.cross,
)
}),
};
let item_writing_mode = non_replaced.style.effective_writing_mode();
let item_is_horizontal = item_writing_mode.is_horizontal();
let cross_axis_is_item_block_axis = cross_axis_is_item_block_axis(
containing_block
.style
.effective_writing_mode()
.is_horizontal(),
item_is_horizontal,
flex_axis,
);
let (inline_size, block_size) = if cross_axis_is_item_block_axis {
(used_main_size, cross_size)
} else {
(
cross_size.auto_is(|| {
let style = non_replaced.style.clone();
let containing_block_for_children =
IndefiniteContainingBlock::new_for_style_and_block_size(
&style,
AuOrAuto::LengthPercentage(used_main_size),
);
let content_contributions = non_replaced
.inline_content_sizes(
flex_context.layout_context,
&containing_block_for_children,
)
.map(|size| {
size.clamp_between_extremums(
self.content_min_size.cross,
self.content_max_size.cross,
)
});
(containing_block.inline_size - self.pbm_auto_is_zero.cross)
.min(content_contributions.max_content)
.max(content_contributions.min_content)
}),
// The main size of a flex item is considered to be definite if its flex basis is definite
// or the flex container has a definite main size.
// <https://drafts.csswg.org/css-flexbox-1/#definite-sizes>
if self.flex_base_size_is_definite ||
flex_context.container_definite_inner_size.main.is_some()
{
AuOrAuto::LengthPercentage(used_main_size)
} else {
AuOrAuto::Auto
},
)
};
let item_as_containing_block = ContainingBlock { let item_as_containing_block = ContainingBlock {
inline_size, inline_size,
block_size, block_size,
@ -1903,10 +1945,11 @@ impl FlexItemBox {
layout_context: &LayoutContext, layout_context: &LayoutContext,
containing_block: &IndefiniteContainingBlock, containing_block: &IndefiniteContainingBlock,
container_is_horizontal: bool, container_is_horizontal: bool,
flex_axis: FlexAxis, config: &FlexContainerConfig,
main_start_cross_start: MainStartCrossStart,
flex_context_getter: &impl Fn() -> &'a FlexContext<'a>, flex_context_getter: &impl Fn() -> &'a FlexContext<'a>,
) -> FlexItemBoxInlineContentSizesInfo { ) -> FlexItemBoxInlineContentSizesInfo {
let flex_axis = config.flex_axis;
let main_start_cross_start = config.main_start_cross_start_sides_are;
let style = self.style().clone(); let style = self.style().clone();
let item_writing_mode = style.effective_writing_mode(); let item_writing_mode = style.effective_writing_mode();
let item_is_horizontal = item_writing_mode.is_horizontal(); let item_is_horizontal = item_writing_mode.is_horizontal();
@ -1915,6 +1958,19 @@ impl FlexItemBox {
let (content_box_size, content_min_size, content_max_size, pbm) = let (content_box_size, content_min_size, content_max_size, pbm) =
style.content_box_sizes_and_padding_border_margin(containing_block); style.content_box_sizes_and_padding_border_margin(containing_block);
let padding = main_start_cross_start.sides_to_flex_relative(pbm.padding);
let border = main_start_cross_start.sides_to_flex_relative(pbm.border);
let margin = main_start_cross_start.sides_to_flex_relative(pbm.margin);
let padding_border = padding.sum_by_axis() + border.sum_by_axis();
let margin_auto_is_zero = pbm.margin.auto_is(Au::zero);
let margin_auto_is_zero =
main_start_cross_start.sides_to_flex_relative(margin_auto_is_zero);
let pbm_auto_is_zero = FlexRelativeVec2 {
main: padding_border.main,
cross: padding_border.cross,
} + margin_auto_is_zero.sum_by_axis();
let item_with_auto_cross_size_stretches_to_container_size =
config.item_with_auto_cross_size_stretches_to_container_size(&style, &margin);
let automatic_min_size = self.automatic_min_size( let automatic_min_size = self.automatic_min_size(
layout_context, layout_context,
containing_block, containing_block,
@ -1922,6 +1978,8 @@ impl FlexItemBox {
flex_axis.vec2_to_flex_relative(content_box_size), flex_axis.vec2_to_flex_relative(content_box_size),
flex_axis.vec2_to_flex_relative(content_min_size), flex_axis.vec2_to_flex_relative(content_min_size),
flex_axis.vec2_to_flex_relative(content_max_size), flex_axis.vec2_to_flex_relative(content_max_size),
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
|item| { |item| {
item.layout_for_block_content_size( item.layout_for_block_content_size(
flex_context_getter(), flex_context_getter(),
@ -1929,6 +1987,7 @@ impl FlexItemBox {
content_box_size, content_box_size,
content_min_size.map(|v| v.auto_is(Au::zero)), content_min_size.map(|v| v.auto_is(Au::zero)),
content_max_size, content_max_size,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size, IntrinsicSizingMode::Size,
) )
}, },
@ -1951,6 +2010,7 @@ impl FlexItemBox {
content_box_size, content_box_size,
content_min_size_no_auto, content_min_size_no_auto,
content_max_size, content_max_size,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Size, IntrinsicSizingMode::Size,
) )
}; };
@ -1964,6 +2024,7 @@ impl FlexItemBox {
layout_context, layout_context,
containing_block, containing_block,
&content_min_size_no_auto, &content_min_size_no_auto,
item_with_auto_cross_size_stretches_to_container_size,
), ),
FlexAxis::Column => self FlexAxis::Column => self
.layout_for_block_content_size( .layout_for_block_content_size(
@ -1972,6 +2033,7 @@ impl FlexItemBox {
content_box_size, content_box_size,
content_min_size_no_auto, content_min_size_no_auto,
content_max_size, content_max_size,
item_with_auto_cross_size_stretches_to_container_size,
IntrinsicSizingMode::Contribution, IntrinsicSizingMode::Contribution,
) )
.into(), .into(),
@ -1981,31 +2043,21 @@ impl FlexItemBox {
let content_min_size_no_auto = flex_axis.vec2_to_flex_relative(content_min_size_no_auto); let content_min_size_no_auto = flex_axis.vec2_to_flex_relative(content_min_size_no_auto);
let content_max_size = flex_axis.vec2_to_flex_relative(content_max_size); let content_max_size = flex_axis.vec2_to_flex_relative(content_max_size);
let padding = main_start_cross_start.sides_to_flex_relative(pbm.padding);
let border = main_start_cross_start.sides_to_flex_relative(pbm.border);
let padding_border = padding.sum_by_axis() + border.sum_by_axis();
let margin_auto_is_zero = pbm.margin.auto_is(Au::zero);
let margin_auto_is_zero =
main_start_cross_start.sides_to_flex_relative(margin_auto_is_zero);
let pbm_auto_is_zero = FlexRelativeVec2 {
main: padding_border.main,
cross: padding_border.cross,
} + margin_auto_is_zero.sum_by_axis();
// TODO: when laying out a column container with an indefinite main size, // TODO: when laying out a column container with an indefinite main size,
// we compute the base sizes of the items twice. We should consider caching. // we compute the base sizes of the items twice. We should consider caching.
let (flex_base_size, _) = self.flex_base_size( let (flex_base_size, _) = self.flex_base_size(
layout_context, layout_context,
containing_block, containing_block,
FlexRelativeVec2 { config
main: None, .flex_axis
cross: None, .vec2_to_flex_relative(containing_block.size.map(|v| v.non_auto())),
},
cross_axis_is_item_block_axis, cross_axis_is_item_block_axis,
content_box_size, content_box_size,
content_min_size_no_auto, content_min_size_no_auto,
content_max_size, content_max_size,
padding_border, padding_border,
&pbm_auto_is_zero,
item_with_auto_cross_size_stretches_to_container_size,
block_content_size_callback, block_content_size_callback,
); );
@ -2109,6 +2161,8 @@ impl FlexItemBox {
content_box_size: FlexRelativeVec2<AuOrAuto>, content_box_size: FlexRelativeVec2<AuOrAuto>,
min_size: FlexRelativeVec2<GenericLengthPercentageOrAuto<Au>>, min_size: FlexRelativeVec2<GenericLengthPercentageOrAuto<Au>>,
max_size: FlexRelativeVec2<Option<Au>>, max_size: FlexRelativeVec2<Option<Au>>,
pbm_auto_is_zero: &FlexRelativeVec2<Au>,
auto_cross_size_stretches_to_container_size: bool,
block_content_size_callback: impl FnOnce(&mut FlexItemBox) -> Au, block_content_size_callback: impl FnOnce(&mut FlexItemBox) -> Au,
) -> Au { ) -> Au {
// FIXME(stshine): Consider more situations when auto min size is not needed. // FIXME(stshine): Consider more situations when auto min size is not needed.
@ -2137,14 +2191,25 @@ impl FlexItemBox {
Direction::Block Direction::Block
}; };
let cross_size =
if content_box_size.cross.is_auto() && auto_cross_size_stretches_to_container_size {
if cross_axis_is_item_block_axis {
containing_block.size.block
} else {
containing_block.size.inline
}
.map(|v| v - pbm_auto_is_zero.cross)
} else {
content_box_size.cross
}
.map(|v| v.clamp_between_extremums(min_size.cross.auto_is(Au::zero), max_size.cross));
// > **transferred size suggestion** // > **transferred size suggestion**
// > If the item has a preferred aspect ratio and its preferred cross size is definite, then the // > If the item has a preferred aspect ratio and its preferred cross size is definite, then the
// > transferred size suggestion is that size (clamped by its minimum and maximum cross sizes if they // > transferred size suggestion is that size (clamped by its minimum and maximum cross sizes if they
// > are definite), converted through the aspect ratio. It is otherwise undefined. // > are definite), converted through the aspect ratio. It is otherwise undefined.
let transferred_size_suggestion = match (ratio, content_box_size.cross) { let transferred_size_suggestion = match (ratio, cross_size) {
(Some(ratio), AuOrAuto::LengthPercentage(cross_size)) => { (Some(ratio), AuOrAuto::LengthPercentage(cross_size)) => {
let cross_size = cross_size
.clamp_between_extremums(min_size.cross.auto_is(Au::zero), max_size.cross);
Some(ratio.compute_dependent_size(main_axis, cross_size)) Some(ratio.compute_dependent_size(main_axis, cross_size))
}, },
_ => None, _ => None,
@ -2155,12 +2220,9 @@ impl FlexItemBox {
// > preferred aspect ratio, by any definite minimum and maximum cross sizes converted through the // > preferred aspect ratio, by any definite minimum and maximum cross sizes converted through the
// > aspect ratio. // > aspect ratio.
let main_content_size = if cross_axis_is_item_block_axis { let main_content_size = if cross_axis_is_item_block_axis {
let block_size = content_box_size.cross.map(|v| {
v.clamp_between_extremums(min_size.cross.auto_is(Au::zero), max_size.cross)
});
let style = self.independent_formatting_context.style().clone(); let style = self.independent_formatting_context.style().clone();
let containing_block_for_children = let containing_block_for_children =
IndefiniteContainingBlock::new_for_style_and_block_size(&style, block_size); IndefiniteContainingBlock::new_for_style_and_block_size(&style, cross_size);
self.independent_formatting_context self.independent_formatting_context
.inline_content_sizes( .inline_content_sizes(
layout_context, layout_context,
@ -2204,9 +2266,11 @@ impl FlexItemBox {
container_definite_inner_size: FlexRelativeVec2<Option<Au>>, container_definite_inner_size: FlexRelativeVec2<Option<Au>>,
cross_axis_is_item_block_axis: bool, cross_axis_is_item_block_axis: bool,
content_box_size: FlexRelativeVec2<AuOrAuto>, content_box_size: FlexRelativeVec2<AuOrAuto>,
min_size: FlexRelativeVec2<Au>, content_min_box_size: FlexRelativeVec2<Au>,
max_size: FlexRelativeVec2<Option<Au>>, content_max_box_size: FlexRelativeVec2<Option<Au>>,
padding_border_sums: FlexRelativeVec2<Au>, padding_border_sums: FlexRelativeVec2<Au>,
pbm_auto_is_zero: &FlexRelativeVec2<Au>,
item_with_auto_cross_size_stretches_to_container_size: bool,
block_content_size_callback: impl FnOnce(&mut FlexItemBox) -> Au, block_content_size_callback: impl FnOnce(&mut FlexItemBox) -> Au,
) -> (Au, bool) { ) -> (Au, bool) {
let flex_item = &mut self.independent_formatting_context; let flex_item = &mut self.independent_formatting_context;
@ -2268,7 +2332,38 @@ impl FlexItemBox {
(length, true) (length, true)
}, },
FlexBasis::Content => { FlexBasis::Content => {
// FIXME: implement cases B, C, D. // > B: If the flex item has ...
// > - a preferred aspect ratio,
// > - a used flex basis of content, and
// > - a definite cross size,
// > then the flex base size is calculated from its used cross size and the flex items aspect ratio.
let ratio = flex_item.preferred_aspect_ratio(containing_block);
let main_axis = if cross_axis_is_item_block_axis {
Direction::Inline
} else {
Direction::Block
};
// > If a single-line flex container has a definite cross size, the automatic preferred
// > outer cross size of any stretched flex items is the flex containers inner cross size
// > (clamped to the flex items min and max cross size) and is considered definite.
let cross_size = if content_box_size.cross.is_auto() &&
item_with_auto_cross_size_stretches_to_container_size
{
container_definite_inner_size
.cross
.map(|v| v - pbm_auto_is_zero.cross)
} else {
content_box_size.cross.non_auto()
};
if let (Some(ratio), Some(cross_size)) = (ratio, cross_size) {
let cross_size = cross_size.clamp_between_extremums(
content_min_box_size.cross,
content_max_box_size.cross,
);
return (ratio.compute_dependent_size(main_axis, cross_size), true);
}
// FIXME: implement cases C, D.
// > E. Otherwise, size the item into the available space using its used flex basis in place of // > E. Otherwise, size the item into the available space using its used flex basis in place of
// > its main size, treating a value of content as max-content. If a cross size is needed to // > its main size, treating a value of content as max-content. If a cross size is needed to
@ -2279,19 +2374,32 @@ impl FlexItemBox {
let flex_basis = if cross_axis_is_item_block_axis { let flex_basis = if cross_axis_is_item_block_axis {
// The main axis is the inline axis, so we can get the content size from the normal // The main axis is the inline axis, so we can get the content size from the normal
// preferred widths calculation. // preferred widths calculation.
let style = style.clone(); let style = flex_item.style().clone();
let block_size = content_box_size let block_size = content_box_size.cross.map(|v| {
.cross v.clamp_between_extremums(
.map(|v| v.clamp_between_extremums(min_size.cross, max_size.cross)); content_min_box_size.cross,
content_max_box_size.cross,
)
});
let containing_block_for_children = let containing_block_for_children =
IndefiniteContainingBlock::new_for_style_and_block_size(&style, block_size); IndefiniteContainingBlock::new_for_style_and_block_size(&style, block_size);
flex_item let max_content = flex_item
.inline_content_sizes( .inline_content_sizes(
layout_context, layout_context,
&containing_block_for_children, &containing_block_for_children,
containing_block, containing_block,
) )
.max_content .max_content;
if let Some(ratio) = ratio {
max_content.clamp_between_extremums(
ratio.compute_dependent_size(main_axis, content_min_box_size.cross),
content_max_box_size
.cross
.map(|v| ratio.compute_dependent_size(main_axis, v)),
)
} else {
max_content
}
} else { } else {
block_content_size_callback(self) block_content_size_callback(self)
}; };
@ -2304,9 +2412,10 @@ impl FlexItemBox {
&mut self, &mut self,
flex_context: &FlexContext, flex_context: &FlexContext,
padding_border_margin: &PaddingBorderMargin, padding_border_margin: &PaddingBorderMargin,
content_box_size: LogicalVec2<AuOrAuto>, mut content_box_size: LogicalVec2<AuOrAuto>,
min_size: LogicalVec2<Au>, mut min_size: LogicalVec2<Au>,
max_size: LogicalVec2<Option<Au>>, mut max_size: LogicalVec2<Option<Au>>,
item_with_auto_cross_size_stretches_to_container_size: bool,
intrinsic_sizing_mode: IntrinsicSizingMode, intrinsic_sizing_mode: IntrinsicSizingMode,
) -> Au { ) -> Au {
let mut positioning_context = PositioningContext::new_for_subtree( let mut positioning_context = PositioningContext::new_for_subtree(
@ -2317,14 +2426,22 @@ impl FlexItemBox {
match &mut self.independent_formatting_context { match &mut self.independent_formatting_context {
IndependentFormattingContext::Replaced(replaced) => { IndependentFormattingContext::Replaced(replaced) => {
// TODO: handle intrinsic_sizing_mode. content_box_size.inline = content_box_size.inline.map(|v| v.max(Au::zero()));
let size = replaced.contents.used_size_as_if_inline_element( if intrinsic_sizing_mode == IntrinsicSizingMode::Size {
flex_context.containing_block, content_box_size.block = AuOrAuto::Auto;
&replaced.style, min_size.block = Au::zero();
None, max_size.block = None;
padding_border_margin, }
); replaced
size.block .contents
.used_size_as_if_inline_element_from_content_box_sizes(
flex_context.containing_block,
&replaced.style,
content_box_size,
min_size,
max_size,
)
.block
}, },
IndependentFormattingContext::NonReplaced(non_replaced) => { IndependentFormattingContext::NonReplaced(non_replaced) => {
// TODO: This is wrong if the item writing mode is different from the flex // TODO: This is wrong if the item writing mode is different from the flex
@ -2332,18 +2449,11 @@ impl FlexItemBox {
let inline_size = content_box_size let inline_size = content_box_size
.inline .inline
.auto_is(|| { .auto_is(|| {
let will_stretch = flex_context
.align_for(non_replaced.style.clone_align_self())
.0 ==
AlignFlags::STRETCH &&
!padding_border_margin.margin.inline_start.is_auto() &&
!padding_border_margin.margin.inline_end.is_auto();
let containing_block_inline_size_minus_pbm = let containing_block_inline_size_minus_pbm =
flex_context.containing_block.inline_size - flex_context.containing_block.inline_size -
padding_border_margin.padding_border_sums.inline; padding_border_margin.padding_border_sums.inline;
if will_stretch { if item_with_auto_cross_size_stretches_to_container_size {
containing_block_inline_size_minus_pbm containing_block_inline_size_minus_pbm
} else { } else {
let style = non_replaced.style.clone(); let style = non_replaced.style.clone();

View file

@ -980,7 +980,6 @@ impl FloatBox {
content_size = replaced.contents.used_size_as_if_inline_element( content_size = replaced.contents.used_size_as_if_inline_element(
containing_block, containing_block,
&replaced.style, &replaced.style,
None,
&pbm, &pbm,
); );
children = replaced.contents.make_fragments( children = replaced.contents.make_fragments(

View file

@ -1917,12 +1917,7 @@ impl IndependentFormattingContext {
IndependentFormattingContext::Replaced(replaced) => { IndependentFormattingContext::Replaced(replaced) => {
let size = replaced let size = replaced
.contents .contents
.used_size_as_if_inline_element( .used_size_as_if_inline_element(layout.containing_block, &replaced.style, &pbm)
layout.containing_block,
&replaced.style,
None,
&pbm,
)
.to_physical_size(container_writing_mode); .to_physical_size(container_writing_mode);
let fragments = replaced.contents.make_fragments(&replaced.style, size); let fragments = replaced.contents.make_fragments(&replaced.style, size);
let content_rect = PhysicalRect::new(pbm_physical_origin, size); let content_rect = PhysicalRect::new(pbm_physical_origin, size);
@ -2383,6 +2378,7 @@ impl<'layout_data> ContentSizesComputation<'layout_data> {
self.layout_context, self.layout_context,
self.containing_block, self.containing_block,
&LogicalVec2::zero(), &LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */
); );
if !inline_formatting_context if !inline_formatting_context

View file

@ -372,6 +372,7 @@ fn calculate_inline_content_size_for_block_level_boxes(
layout_context, layout_context,
containing_block, containing_block,
&LogicalVec2::zero(), &LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */
) )
.max(ContentSizes::zero()); .max(ContentSizes::zero());
let style_box = &float_box.contents.style().get_box(); let style_box = &float_box.contents.style().get_box();
@ -384,6 +385,7 @@ fn calculate_inline_content_size_for_block_level_boxes(
style, style,
&containing_block, &containing_block,
&LogicalVec2::zero(), &LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */
|containing_block_for_children| { |containing_block_for_children| {
contents.inline_content_sizes(layout_context, containing_block_for_children) contents.inline_content_sizes(layout_context, containing_block_for_children)
}, },
@ -400,6 +402,7 @@ fn calculate_inline_content_size_for_block_level_boxes(
layout_context, layout_context,
containing_block, containing_block,
&LogicalVec2::zero(), &LogicalVec2::zero(),
false, /* auto_block_size_stretches_to_containing_block */
) )
.max(ContentSizes::zero()); .max(ContentSizes::zero());
Some((size, Float::None, independent.style().get_box().clear)) Some((size, Float::None, independent.style().get_box().clear))
@ -1296,7 +1299,7 @@ fn layout_in_flow_replaced_block_level(
mut sequential_layout_state: Option<&mut SequentialLayoutState>, mut sequential_layout_state: Option<&mut SequentialLayoutState>,
) -> BoxFragment { ) -> BoxFragment {
let pbm = style.padding_border_margin(containing_block); let pbm = style.padding_border_margin(containing_block);
let content_size = replaced.used_size_as_if_inline_element(containing_block, style, None, &pbm); let content_size = replaced.used_size_as_if_inline_element(containing_block, style, &pbm);
let margin_inline_start; let margin_inline_start;
let margin_inline_end; let margin_inline_end;

View file

@ -198,12 +198,14 @@ impl IndependentFormattingContext {
layout_context: &LayoutContext, layout_context: &LayoutContext,
containing_block: &IndefiniteContainingBlock, containing_block: &IndefiniteContainingBlock,
auto_minimum: &LogicalVec2<Au>, auto_minimum: &LogicalVec2<Au>,
auto_block_size_stretches_to_containing_block: bool,
) -> ContentSizes { ) -> ContentSizes {
match self { match self {
Self::NonReplaced(non_replaced) => sizing::outer_inline( Self::NonReplaced(non_replaced) => sizing::outer_inline(
&non_replaced.style.clone(), &non_replaced.style.clone(),
containing_block, containing_block,
auto_minimum, auto_minimum,
auto_block_size_stretches_to_containing_block,
|containing_block_for_children| { |containing_block_for_children| {
non_replaced.inline_content_sizes(layout_context, containing_block_for_children) non_replaced.inline_content_sizes(layout_context, containing_block_for_children)
}, },
@ -212,6 +214,7 @@ impl IndependentFormattingContext {
&replaced.style, &replaced.style,
containing_block, containing_block,
auto_minimum, auto_minimum,
auto_block_size_stretches_to_containing_block,
|containing_block_for_children| { |containing_block_for_children| {
replaced.contents.inline_content_sizes( replaced.contents.inline_content_sizes(
layout_context, layout_context,
@ -222,6 +225,16 @@ impl IndependentFormattingContext {
), ),
} }
} }
pub(crate) fn preferred_aspect_ratio(
&self,
containing_block: &IndefiniteContainingBlock,
) -> Option<AspectRatio> {
match self {
Self::NonReplaced(_) => None,
Self::Replaced(replaced) => replaced.preferred_aspect_ratio(containing_block),
}
}
} }
impl NonReplacedFormattingContext { impl NonReplacedFormattingContext {

View file

@ -499,7 +499,6 @@ impl HoistedAbsolutelyPositionedBox {
let used_size = replaced.contents.used_size_as_if_inline_element( let used_size = replaced.contents.used_size_as_if_inline_element(
&containing_block.into(), &containing_block.into(),
&replaced.style, &replaced.style,
None,
&pbm, &pbm,
); );
LogicalVec2 { LogicalVec2 {

View file

@ -360,32 +360,50 @@ impl ReplacedContent {
/// ///
/// Also used in other cases, for example /// Also used in other cases, for example
/// <https://drafts.csswg.org/css2/visudet.html#block-replaced-width> /// <https://drafts.csswg.org/css2/visudet.html#block-replaced-width>
pub fn used_size_as_if_inline_element( pub(crate) fn used_size_as_if_inline_element(
&self, &self,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
style: &ComputedValues, style: &ComputedValues,
box_size: Option<LogicalVec2<AuOrAuto>>,
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
) -> LogicalVec2<Au> { ) -> LogicalVec2<Au> {
let mode = style.effective_writing_mode(); let box_size = style
let intrinsic_size = self.flow_relative_intrinsic_size(style); .content_box_size(containing_block, pbm)
let intrinsic_ratio = self.preferred_aspect_ratio(&containing_block.into(), style); // We need to clamp to zero here to obtain the proper aspect
// ratio when box-sizing is border-box and the inner box size
let box_size = box_size.unwrap_or( // would otherwise be negative.
style .map(|v| v.map(|v| Au::from(v).max(Au::zero())));
.content_box_size(containing_block, pbm)
// We need to clamp to zero here to obtain the proper aspect
// ratio when box-sizing is border-box and the inner box size
// would otherwise be negative.
.map(|v| v.map(|v| Au::from(v).max(Au::zero()))),
);
let max_box_size = style
.content_max_box_size(containing_block, pbm)
.map(|v| v.map(Au::from));
let min_box_size = style let min_box_size = style
.content_min_box_size(containing_block, pbm) .content_min_box_size(containing_block, pbm)
.map(|v| v.map(Au::from)) .map(|v| v.map(Au::from))
.auto_is(Au::zero); .auto_is(Au::zero);
let max_box_size = style
.content_max_box_size(containing_block, pbm)
.map(|v| v.map(Au::from));
self.used_size_as_if_inline_element_from_content_box_sizes(
containing_block,
style,
box_size,
min_box_size,
max_box_size,
)
}
/// <https://drafts.csswg.org/css2/visudet.html#inline-replaced-width>
/// <https://drafts.csswg.org/css2/visudet.html#inline-replaced-height>
///
/// Also used in other cases, for example
/// <https://drafts.csswg.org/css2/visudet.html#block-replaced-width>
pub(crate) fn used_size_as_if_inline_element_from_content_box_sizes(
&self,
containing_block: &ContainingBlock,
style: &ComputedValues,
box_size: LogicalVec2<AuOrAuto>,
min_box_size: LogicalVec2<Au>,
max_box_size: LogicalVec2<Option<Au>>,
) -> LogicalVec2<Au> {
let mode = style.effective_writing_mode();
let intrinsic_size = self.flow_relative_intrinsic_size(style);
let intrinsic_ratio = self.preferred_aspect_ratio(&containing_block.into(), style);
let default_object_size = || { let default_object_size = || {
// FIXME: // FIXME:

View file

@ -111,6 +111,7 @@ pub(crate) fn outer_inline(
style: &ComputedValues, style: &ComputedValues,
containing_block: &IndefiniteContainingBlock, containing_block: &IndefiniteContainingBlock,
auto_minimum: &LogicalVec2<Au>, auto_minimum: &LogicalVec2<Au>,
auto_block_size_stretches_to_containing_block: bool,
get_content_size: impl FnOnce(&IndefiniteContainingBlock) -> ContentSizes, get_content_size: impl FnOnce(&IndefiniteContainingBlock) -> ContentSizes,
) -> ContentSizes { ) -> ContentSizes {
let (content_box_size, content_min_size, content_max_size, pbm) = let (content_box_size, content_min_size, content_max_size, pbm) =
@ -119,18 +120,23 @@ pub(crate) fn outer_inline(
inline: content_min_size.inline.auto_is(|| auto_minimum.inline), inline: content_min_size.inline.auto_is(|| auto_minimum.inline),
block: content_min_size.block.auto_is(|| auto_minimum.block), block: content_min_size.block.auto_is(|| auto_minimum.block),
}; };
let pbm_inline_sum = pbm.padding_border_sums.inline + let margin = pbm.margin.map(|v| v.auto_is(Au::zero));
pbm.margin.inline_start.auto_is(Au::zero) + let pbm_inline_sum = pbm.padding_border_sums.inline + margin.inline_sum();
pbm.margin.inline_end.auto_is(Au::zero);
let adjust = |v: Au| { let adjust = |v: Au| {
v.clamp_between_extremums(content_min_size.inline, content_max_size.inline) + pbm_inline_sum v.clamp_between_extremums(content_min_size.inline, content_max_size.inline) + pbm_inline_sum
}; };
match content_box_size.inline { match content_box_size.inline {
AuOrAuto::LengthPercentage(inline_size) => adjust(inline_size).into(), AuOrAuto::LengthPercentage(inline_size) => adjust(inline_size).into(),
AuOrAuto::Auto => { AuOrAuto::Auto => {
let block_size = content_box_size let block_size = if content_box_size.block.is_auto() &&
.block auto_block_size_stretches_to_containing_block
.map(|v| v.clamp_between_extremums(content_min_size.block, content_max_size.block)); {
let outer_block_size = containing_block.size.block;
outer_block_size.map(|v| v - pbm.padding_border_sums.block - margin.block_sum())
} else {
content_box_size.block
}
.map(|v| v.clamp_between_extremums(content_min_size.block, content_max_size.block));
let containing_block_for_children = let containing_block_for_children =
IndefiniteContainingBlock::new_for_style_and_block_size(style, block_size); IndefiniteContainingBlock::new_for_style_and_block_size(style, block_size);
get_content_size(&containing_block_for_children).map(adjust) get_content_size(&containing_block_for_children).map(adjust)

View file

@ -1,2 +0,0 @@
[aspect-ratio-intrinsic-size-001.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[aspect-ratio-intrinsic-size-002.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[aspect-ratio-intrinsic-size-006.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[css-flexbox-img-expand-evenly.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-aspect-ratio-img-column-010.html]
expected: FAIL

View file

@ -1,9 +1,3 @@
[flex-aspect-ratio-img-column-011.html] [flex-aspect-ratio-img-column-011.html]
[.flexbox 7] [.flexbox 7]
expected: FAIL expected: FAIL
[.flexbox 1]
expected: FAIL
[.flexbox 3]
expected: FAIL

View file

@ -1,3 +0,0 @@
[flex-aspect-ratio-img-row-005.html]
[img 3]
expected: FAIL

View file

@ -1,15 +0,0 @@
[flex-aspect-ratio-img-row-013.html]
[img 1]
expected: FAIL
[img 2]
expected: FAIL
[img 3]
expected: FAIL
[img 4]
expected: FAIL
[img 5]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-height-flex-items-020.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-height-flex-items-021.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-minimum-width-flex-items-013.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-flex-basis-content-002a.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-flex-basis-content-002b.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-min-width-auto-002a.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-min-width-auto-002b.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox-min-width-auto-002c.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flexbox_align-items-stretch-4.html]
expected: FAIL

View file

@ -1,4 +0,0 @@
[flexitem-stretch-image.html]
[.flexbox 1]
expected: FAIL

View file

@ -1,15 +0,0 @@
[image-as-flexitem-size-001.html]
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 10]
expected: FAIL
[.flexbox > img 11]
expected: FAIL

View file

@ -1,15 +0,0 @@
[image-as-flexitem-size-001v.html]
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 11]
expected: FAIL
[.flexbox > img 10]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL

View file

@ -1,3 +0,0 @@
[image-as-flexitem-size-002.html]
[.flexbox > img 4]
expected: FAIL

View file

@ -1,3 +0,0 @@
[image-as-flexitem-size-002v.html]
[.flexbox > img 4]
expected: FAIL

View file

@ -1,21 +0,0 @@
[image-as-flexitem-size-003.html]
[.flexbox > img 1]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 11]
expected: FAIL
[.flexbox > img 10]
expected: FAIL

View file

@ -1,21 +0,0 @@
[image-as-flexitem-size-003v.html]
[.flexbox > img 1]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 11]
expected: FAIL
[.flexbox > img 10]
expected: FAIL

View file

@ -1,15 +0,0 @@
[image-as-flexitem-size-004.html]
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 1]
expected: FAIL

View file

@ -1,15 +0,0 @@
[image-as-flexitem-size-004v.html]
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 1]
expected: FAIL

View file

@ -1,24 +0,0 @@
[image-as-flexitem-size-005.html]
[.flexbox > img 18]
expected: FAIL
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 1]
expected: FAIL
[.flexbox > img 2]
expected: FAIL

View file

@ -1,24 +0,0 @@
[image-as-flexitem-size-005v.html]
[.flexbox > img 18]
expected: FAIL
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 1]
expected: FAIL
[.flexbox > img 2]
expected: FAIL

View file

@ -1,24 +0,0 @@
[image-as-flexitem-size-006.html]
[.flexbox > img 15]
expected: FAIL
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 1]
expected: FAIL
[.flexbox > img 3]
expected: FAIL

View file

@ -1,24 +0,0 @@
[image-as-flexitem-size-006v.html]
[.flexbox > img 15]
expected: FAIL
[.flexbox > img 8]
expected: FAIL
[.flexbox > img 5]
expected: FAIL
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 1]
expected: FAIL
[.flexbox > img 3]
expected: FAIL

View file

@ -1,15 +0,0 @@
[image-as-flexitem-size-007.html]
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 6]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 10]
expected: FAIL
[.flexbox > img 11]
expected: FAIL

View file

@ -1,15 +0,0 @@
[image-as-flexitem-size-007v.html]
[.flexbox > img 4]
expected: FAIL
[.flexbox > img 11]
expected: FAIL
[.flexbox > img 10]
expected: FAIL
[.flexbox > img 7]
expected: FAIL
[.flexbox > img 6]
expected: FAIL

View file

@ -0,0 +1,3 @@
[row-use-cases-001.html]
[same heights]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-aspect-ratio-023.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[flex-aspect-ratio-024.html]
expected: FAIL