mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Take into account the intrinsic block size when computing the main size of a column flex container (#33135)
In particular, `main_content_sizes()` now works with columns. `layout_for_block_content_size()` is now used for both intrinsic sizes and intrinsic contributions, a IntrinsicSizingMode parameter is added to choose the behavior. Also, we consider the main size of a flex item as indefinite if its flex basis is indefinite and the flex container has an indefinite main size. Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
cf98d8d7ec
commit
c00cd1326a
36 changed files with 290 additions and 213 deletions
|
@ -30,7 +30,7 @@ use crate::formatting_contexts::{Baselines, IndependentFormattingContext, Indepe
|
||||||
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags};
|
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags};
|
||||||
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2};
|
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||||
use crate::sizing::ContentSizes;
|
use crate::sizing::{ContentSizes, IntrinsicSizingMode};
|
||||||
use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin};
|
use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin};
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
|
|
||||||
|
@ -68,6 +68,11 @@ struct FlexItem<'a> {
|
||||||
/// <https://drafts.csswg.org/css-flexbox/#algo-main-item>
|
/// <https://drafts.csswg.org/css-flexbox/#algo-main-item>
|
||||||
flex_base_size: Au,
|
flex_base_size: Au,
|
||||||
|
|
||||||
|
/// Whether the [`Self::flex_base_size`] comes from a definite `flex-basis`.
|
||||||
|
/// If false and the container main size is also indefinite, percentages in the item's
|
||||||
|
/// content that resolve against its main size should be indefinite.
|
||||||
|
flex_base_size_is_definite: bool,
|
||||||
|
|
||||||
/// <https://drafts.csswg.org/css-flexbox/#algo-main-item>
|
/// <https://drafts.csswg.org/css-flexbox/#algo-main-item>
|
||||||
hypothetical_main_size: Au,
|
hypothetical_main_size: Au,
|
||||||
/// This is `align-self`, defaulting to `align-items` if `auto`
|
/// This is `align-self`, defaulting to `align-items` if `auto`
|
||||||
|
@ -173,7 +178,7 @@ impl FlexContext<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Debug, Default)]
|
||||||
struct DesiredFlexFractionAndGrowOrShrinkFactor {
|
struct DesiredFlexFractionAndGrowOrShrinkFactor {
|
||||||
desired_flex_fraction: f32,
|
desired_flex_fraction: f32,
|
||||||
flex_grow_or_shrink_factor: f32,
|
flex_grow_or_shrink_factor: f32,
|
||||||
|
@ -197,7 +202,11 @@ impl FlexContainer {
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
) -> ContentSizes {
|
) -> ContentSizes {
|
||||||
match self.config.flex_axis {
|
match self.config.flex_axis {
|
||||||
FlexAxis::Row => self.main_content_sizes(layout_context, writing_mode),
|
FlexAxis::Row => self.main_content_sizes(layout_context, writing_mode, || {
|
||||||
|
unreachable!(
|
||||||
|
"Unexpected FlexContext query during row flex intrinsic size calculation."
|
||||||
|
)
|
||||||
|
}),
|
||||||
FlexAxis::Column => self.cross_content_sizes(layout_context),
|
FlexAxis::Column => self.cross_content_sizes(layout_context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,10 +236,11 @@ impl FlexContainer {
|
||||||
content_sizes
|
content_sizes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main_content_sizes(
|
fn main_content_sizes<'a>(
|
||||||
&mut self,
|
&self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
|
flex_context_getter: impl Fn() -> &'a FlexContext<'a>,
|
||||||
) -> ContentSizes {
|
) -> ContentSizes {
|
||||||
// - TODO: calculate intrinsic cross sizes when container is a column
|
// - TODO: calculate intrinsic cross sizes when container is a column
|
||||||
// (and check for ‘writing-mode’?)
|
// (and check for ‘writing-mode’?)
|
||||||
|
@ -240,11 +250,6 @@ impl FlexContainer {
|
||||||
// > It is calculated, considering only non-collapsed flex items, by:
|
// > It is calculated, considering only non-collapsed flex items, by:
|
||||||
// > 1. For each flex item, subtract its outer flex base size from its max-content
|
// > 1. For each flex item, subtract its outer flex base size from its max-content
|
||||||
// > contribution size.
|
// > contribution size.
|
||||||
assert_eq!(
|
|
||||||
self.config.flex_axis,
|
|
||||||
FlexAxis::Row,
|
|
||||||
"The main axis should be the inline one"
|
|
||||||
);
|
|
||||||
let mut chosen_max_flex_fraction = f32::NEG_INFINITY;
|
let mut chosen_max_flex_fraction = f32::NEG_INFINITY;
|
||||||
let mut chosen_min_flex_fraction = f32::NEG_INFINITY;
|
let mut chosen_min_flex_fraction = f32::NEG_INFINITY;
|
||||||
let mut sum_of_flex_grow_factors = 0.0;
|
let mut sum_of_flex_grow_factors = 0.0;
|
||||||
|
@ -265,10 +270,11 @@ impl FlexContainer {
|
||||||
container_is_horizontal,
|
container_is_horizontal,
|
||||||
self.config.flex_axis,
|
self.config.flex_axis,
|
||||||
self.config.main_start_cross_start_sides_are,
|
self.config.main_start_cross_start_sides_are,
|
||||||
|
&flex_context_getter,
|
||||||
);
|
);
|
||||||
|
|
||||||
// > 2. Place all flex items into lines of infinite length. Within
|
// > 2. Place all flex items into lines of infinite length. Within
|
||||||
// > each line, find the greatest (most > positive) desired flex
|
// > each line, find the greatest (most positive) desired flex
|
||||||
// > fraction among all the flex items. This is the line’s chosen flex
|
// > fraction among all the flex items. This is the line’s chosen flex
|
||||||
// > fraction.
|
// > fraction.
|
||||||
chosen_max_flex_fraction =
|
chosen_max_flex_fraction =
|
||||||
|
@ -301,16 +307,20 @@ impl FlexContainer {
|
||||||
let chosen_min_flex_fraction = normalize_flex_fraction(chosen_min_flex_fraction);
|
let chosen_min_flex_fraction = normalize_flex_fraction(chosen_min_flex_fraction);
|
||||||
let chosen_max_flex_fraction = normalize_flex_fraction(chosen_max_flex_fraction);
|
let chosen_max_flex_fraction = normalize_flex_fraction(chosen_max_flex_fraction);
|
||||||
|
|
||||||
let column_gap = match self.style.clone_column_gap() {
|
let main_gap = match self.config.flex_axis {
|
||||||
|
FlexAxis::Row => self.style.clone_column_gap(),
|
||||||
|
FlexAxis::Column => self.style.clone_row_gap(),
|
||||||
|
};
|
||||||
|
let main_gap = match main_gap {
|
||||||
LengthPercentageOrNormal::LengthPercentage(length_percentage) => {
|
LengthPercentageOrNormal::LengthPercentage(length_percentage) => {
|
||||||
length_percentage.to_used_value(Au::zero())
|
length_percentage.to_used_value(Au::zero())
|
||||||
},
|
},
|
||||||
LengthPercentageOrNormal::Normal => Au::zero(),
|
LengthPercentageOrNormal::Normal => Au::zero(),
|
||||||
};
|
};
|
||||||
let extra_space_from_column_gap = column_gap * (item_infos.len() as i32 - 1);
|
let extra_space_from_main_gap = main_gap * (item_infos.len() as i32 - 1);
|
||||||
let mut container_max_content_size = extra_space_from_column_gap;
|
let mut container_max_content_size = extra_space_from_main_gap;
|
||||||
let mut container_min_content_size = if self.config.flex_wrap == FlexWrap::Nowrap {
|
let mut container_min_content_size = if self.config.flex_wrap == FlexWrap::Nowrap {
|
||||||
extra_space_from_column_gap
|
extra_space_from_main_gap
|
||||||
} else {
|
} else {
|
||||||
Au::zero()
|
Au::zero()
|
||||||
};
|
};
|
||||||
|
@ -375,6 +385,34 @@ impl FlexContainer {
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
containing_block_for_container: &ContainingBlock,
|
containing_block_for_container: &ContainingBlock,
|
||||||
) -> IndependentLayout {
|
) -> IndependentLayout {
|
||||||
|
let (container_min_cross_size, container_max_cross_size) =
|
||||||
|
self.available_cross_space_for_flex_items(containing_block_for_container);
|
||||||
|
let mut flex_context = FlexContext {
|
||||||
|
config: self.config.clone(),
|
||||||
|
layout_context,
|
||||||
|
positioning_context,
|
||||||
|
containing_block,
|
||||||
|
container_min_cross_size,
|
||||||
|
container_max_cross_size,
|
||||||
|
// https://drafts.csswg.org/css-flexbox/#definite-sizes
|
||||||
|
container_definite_inner_size: self.config.flex_axis.vec2_to_flex_relative(
|
||||||
|
LogicalVec2 {
|
||||||
|
inline: Some(containing_block.inline_size),
|
||||||
|
block: containing_block.block_size.non_auto(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
// “Determine the main size of the flex container”
|
||||||
|
// https://drafts.csswg.org/css-flexbox/#algo-main-container
|
||||||
|
let container_main_size = match self.config.flex_axis {
|
||||||
|
FlexAxis::Row => containing_block.inline_size,
|
||||||
|
FlexAxis::Column => containing_block.block_size.auto_is(|| {
|
||||||
|
self.main_content_sizes(layout_context, self.style.writing_mode, || &flex_context)
|
||||||
|
.max_content
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
// Actual length may be less, but we guess that usually not by a lot
|
// Actual length may be less, but we guess that usually not by a lot
|
||||||
let mut flex_items = Vec::with_capacity(self.children.len());
|
let mut flex_items = Vec::with_capacity(self.children.len());
|
||||||
|
|
||||||
|
@ -406,44 +444,11 @@ impl FlexContainer {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let (container_min_cross_size, container_max_cross_size) =
|
|
||||||
self.available_cross_space_for_flex_items(containing_block_for_container);
|
|
||||||
let mut flex_context = FlexContext {
|
|
||||||
config: self.config.clone(),
|
|
||||||
layout_context,
|
|
||||||
positioning_context,
|
|
||||||
containing_block,
|
|
||||||
container_min_cross_size,
|
|
||||||
container_max_cross_size,
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#definite-sizes
|
|
||||||
container_definite_inner_size: self.config.flex_axis.vec2_to_flex_relative(
|
|
||||||
LogicalVec2 {
|
|
||||||
inline: Some(containing_block.inline_size),
|
|
||||||
block: containing_block.block_size.non_auto(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
let flex_item_boxes = flex_items.iter_mut().map(|child| &mut **child);
|
let flex_item_boxes = flex_items.iter_mut().map(|child| &mut **child);
|
||||||
let mut flex_items = flex_item_boxes
|
let mut flex_items = flex_item_boxes
|
||||||
.map(|flex_item_box| FlexItem::new(&flex_context, flex_item_box))
|
.map(|flex_item_box| FlexItem::new(&flex_context, flex_item_box))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// “Determine the main size of the flex container”
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-main-container
|
|
||||||
let container_main_size = match self.config.flex_axis {
|
|
||||||
FlexAxis::Row => containing_block.inline_size,
|
|
||||||
FlexAxis::Column => {
|
|
||||||
// FIXME “using the rules of the formatting context in which it participates”
|
|
||||||
// but if block-level with `block-size: max-auto` that requires
|
|
||||||
// layout of the content to be fully done:
|
|
||||||
// https://github.com/w3c/csswg-drafts/issues/4905
|
|
||||||
// Gecko reportedly uses `block-size: fit-content` in this case
|
|
||||||
// (which requires running another pass of the "full" layout algorithm)
|
|
||||||
containing_block.block_size.auto_is(Au::zero)
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let row_gap = self.style.clone_row_gap();
|
let row_gap = self.style.clone_row_gap();
|
||||||
let column_gap = self.style.clone_column_gap();
|
let column_gap = self.style.clone_column_gap();
|
||||||
let (cross_gap, main_gap) = match flex_context.config.flex_axis {
|
let (cross_gap, main_gap) = match flex_context.config.flex_axis {
|
||||||
|
@ -844,6 +849,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,
|
||||||
|
IntrinsicSizingMode::Size,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -862,7 +868,7 @@ impl<'a> FlexItem<'a> {
|
||||||
|
|
||||||
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 = box_.flex_base_size(
|
let (flex_base_size, flex_base_size_is_definite) = box_.flex_base_size(
|
||||||
flex_context.layout_context,
|
flex_context.layout_context,
|
||||||
flex_context.container_definite_inner_size,
|
flex_context.container_definite_inner_size,
|
||||||
cross_axis_is_item_block_axis,
|
cross_axis_is_item_block_axis,
|
||||||
|
@ -879,6 +885,7 @@ impl<'a> FlexItem<'a> {
|
||||||
content_box_size,
|
content_box_size,
|
||||||
min_size,
|
min_size,
|
||||||
max_size,
|
max_size,
|
||||||
|
IntrinsicSizingMode::Size,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -899,6 +906,7 @@ impl<'a> FlexItem<'a> {
|
||||||
margin,
|
margin,
|
||||||
pbm_auto_is_zero,
|
pbm_auto_is_zero,
|
||||||
flex_base_size,
|
flex_base_size,
|
||||||
|
flex_base_size_is_definite,
|
||||||
hypothetical_main_size,
|
hypothetical_main_size,
|
||||||
align_self,
|
align_self,
|
||||||
}
|
}
|
||||||
|
@ -1000,16 +1008,7 @@ impl InitialFlexLineLayout<'_> {
|
||||||
let item_layout_results = items
|
let item_layout_results = items
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.zip(&item_used_main_sizes)
|
.zip(&item_used_main_sizes)
|
||||||
.map(|(item, &used_main_size)| {
|
.map(|(item, &used_main_size)| item.layout(used_main_size, &flex_context, None))
|
||||||
item.layout(
|
|
||||||
used_main_size,
|
|
||||||
&flex_context.config,
|
|
||||||
flex_context.containing_block,
|
|
||||||
flex_context.layout_context,
|
|
||||||
flex_context.positioning_context,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-cross-line
|
// https://drafts.csswg.org/css-flexbox/#algo-cross-line
|
||||||
|
@ -1305,14 +1304,8 @@ impl InitialFlexLineLayout<'_> {
|
||||||
// “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.”
|
||||||
*item_layout_result = item.layout(
|
*item_layout_result =
|
||||||
*used_main_size,
|
item.layout(*used_main_size, &flex_context, Some(used_cross_size));
|
||||||
&flex_context.config,
|
|
||||||
flex_context.containing_block,
|
|
||||||
flex_context.layout_context,
|
|
||||||
flex_context.positioning_context,
|
|
||||||
Some(used_cross_size),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This also needs to check whether we have a compatible writing mode.
|
// TODO: This also needs to check whether we have a compatible writing mode.
|
||||||
|
@ -1522,14 +1515,14 @@ impl FlexItem<'_> {
|
||||||
fn layout(
|
fn layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
used_main_size: Au,
|
used_main_size: Au,
|
||||||
config: &FlexContainerConfig,
|
flex_context: &FlexContext,
|
||||||
containing_block: &ContainingBlock,
|
|
||||||
layout_context: &LayoutContext,
|
|
||||||
positioning_context: &PositioningContext,
|
|
||||||
used_cross_size_override: Option<Au>,
|
used_cross_size_override: Option<Au>,
|
||||||
) -> FlexItemLayoutResult {
|
) -> FlexItemLayoutResult {
|
||||||
|
let containing_block = &flex_context.containing_block;
|
||||||
let mut positioning_context = PositioningContext::new_for_subtree(
|
let mut positioning_context = PositioningContext::new_for_subtree(
|
||||||
positioning_context.collects_for_nearest_positioned_ancestor(),
|
flex_context
|
||||||
|
.positioning_context
|
||||||
|
.collects_for_nearest_positioned_ancestor(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
|
// https://drafts.csswg.org/css-writing-modes/#orthogonal-flows
|
||||||
|
@ -1558,7 +1551,11 @@ impl FlexItem<'_> {
|
||||||
box_size,
|
box_size,
|
||||||
&pbm,
|
&pbm,
|
||||||
);
|
);
|
||||||
let cross_size = config.flex_axis.vec2_to_flex_relative(size).cross;
|
let cross_size = flex_context
|
||||||
|
.config
|
||||||
|
.flex_axis
|
||||||
|
.vec2_to_flex_relative(size)
|
||||||
|
.cross;
|
||||||
let fragments = replaced.contents.make_fragments(
|
let fragments = replaced.contents.make_fragments(
|
||||||
&replaced.style,
|
&replaced.style,
|
||||||
size.to_physical_size(container_writing_mode),
|
size.to_physical_size(container_writing_mode),
|
||||||
|
@ -1589,7 +1586,7 @@ impl FlexItem<'_> {
|
||||||
.effective_writing_mode()
|
.effective_writing_mode()
|
||||||
.is_horizontal(),
|
.is_horizontal(),
|
||||||
item_is_horizontal,
|
item_is_horizontal,
|
||||||
config.flex_axis,
|
flex_context.config.flex_axis,
|
||||||
);
|
);
|
||||||
let (inline_size, block_size) = if cross_axis_is_item_block_axis {
|
let (inline_size, block_size) = if cross_axis_is_item_block_axis {
|
||||||
(used_main_size, cross_size)
|
(used_main_size, cross_size)
|
||||||
|
@ -1597,7 +1594,7 @@ impl FlexItem<'_> {
|
||||||
(
|
(
|
||||||
cross_size.auto_is(|| {
|
cross_size.auto_is(|| {
|
||||||
let content_contributions = non_replaced.outer_inline_content_sizes(
|
let content_contributions = non_replaced.outer_inline_content_sizes(
|
||||||
layout_context,
|
flex_context.layout_context,
|
||||||
container_writing_mode,
|
container_writing_mode,
|
||||||
Au::zero,
|
Au::zero,
|
||||||
);
|
);
|
||||||
|
@ -1607,7 +1604,16 @@ impl FlexItem<'_> {
|
||||||
.max(content_contributions.min_content) -
|
.max(content_contributions.min_content) -
|
||||||
self.pbm_auto_is_zero.cross
|
self.pbm_auto_is_zero.cross
|
||||||
}),
|
}),
|
||||||
AuOrAuto::LengthPercentage(used_main_size),
|
// 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
|
||||||
|
},
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1622,7 +1628,7 @@ impl FlexItem<'_> {
|
||||||
baselines: content_box_baselines,
|
baselines: content_box_baselines,
|
||||||
..
|
..
|
||||||
} = non_replaced.layout(
|
} = non_replaced.layout(
|
||||||
layout_context,
|
flex_context.layout_context,
|
||||||
&mut positioning_context,
|
&mut positioning_context,
|
||||||
&item_as_containing_block,
|
&item_as_containing_block,
|
||||||
containing_block,
|
containing_block,
|
||||||
|
@ -1809,13 +1815,14 @@ impl FlexItem<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlexItemBox {
|
impl FlexItemBox {
|
||||||
fn main_content_size_info(
|
fn main_content_size_info<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
container_writing_mode: WritingMode,
|
container_writing_mode: WritingMode,
|
||||||
container_is_horizontal: bool,
|
container_is_horizontal: bool,
|
||||||
flex_axis: FlexAxis,
|
flex_axis: FlexAxis,
|
||||||
main_start_cross_start: MainStartCrossStart,
|
main_start_cross_start: MainStartCrossStart,
|
||||||
|
flex_context_getter: &impl Fn() -> &'a FlexContext<'a>,
|
||||||
) -> FlexItemBoxInlineContentSizesInfo {
|
) -> FlexItemBoxInlineContentSizesInfo {
|
||||||
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();
|
||||||
|
@ -1848,18 +1855,57 @@ 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),
|
||||||
|_| {
|
|item| {
|
||||||
unreachable!(
|
item.layout_for_block_content_size(
|
||||||
"Unexpected block size query during row flex intrinsic size calculation."
|
flex_context_getter(),
|
||||||
|
&pbm,
|
||||||
|
content_box_size,
|
||||||
|
content_min_size.map(|v| v.auto_is(Au::zero)),
|
||||||
|
content_max_size,
|
||||||
|
IntrinsicSizingMode::Size,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let content_box_size = flex_axis.vec2_to_flex_relative(content_box_size);
|
|
||||||
let content_min_size_no_auto = LogicalVec2 {
|
let content_min_size_no_auto = LogicalVec2 {
|
||||||
inline: content_min_size.inline.auto_is(|| automatic_min_size),
|
inline: content_min_size.inline.auto_is(|| automatic_min_size),
|
||||||
block: content_min_size.block.auto_is(Au::zero),
|
block: content_min_size.block.auto_is(Au::zero),
|
||||||
};
|
};
|
||||||
|
let block_content_size_callback = |item: &mut FlexItemBox| {
|
||||||
|
item.layout_for_block_content_size(
|
||||||
|
flex_context_getter(),
|
||||||
|
&pbm,
|
||||||
|
content_box_size,
|
||||||
|
content_min_size_no_auto,
|
||||||
|
content_max_size,
|
||||||
|
IntrinsicSizingMode::Size,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Compute the min-content and max-content contributions of the item.
|
||||||
|
// <https://drafts.csswg.org/css-flexbox/#intrinsic-item-contributions>
|
||||||
|
let content_contribution_sizes = match flex_axis {
|
||||||
|
FlexAxis::Row => self
|
||||||
|
.independent_formatting_context
|
||||||
|
.outer_inline_content_sizes(layout_context, container_writing_mode, || {
|
||||||
|
automatic_min_size
|
||||||
|
}),
|
||||||
|
FlexAxis::Column => {
|
||||||
|
let size = self.layout_for_block_content_size(
|
||||||
|
flex_context_getter(),
|
||||||
|
&pbm,
|
||||||
|
content_box_size,
|
||||||
|
content_min_size_no_auto,
|
||||||
|
content_max_size,
|
||||||
|
IntrinsicSizingMode::Contribution,
|
||||||
|
);
|
||||||
|
ContentSizes {
|
||||||
|
min_content: size,
|
||||||
|
max_content: size,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let content_box_size = flex_axis.vec2_to_flex_relative(content_box_size);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -1874,7 +1920,9 @@ impl FlexItemBox {
|
||||||
cross: padding_border.cross,
|
cross: padding_border.cross,
|
||||||
} + margin_auto_is_zero.sum_by_axis();
|
} + margin_auto_is_zero.sum_by_axis();
|
||||||
|
|
||||||
let flex_base_size = self.flex_base_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.
|
||||||
|
let (flex_base_size, _) = self.flex_base_size(
|
||||||
layout_context,
|
layout_context,
|
||||||
FlexRelativeVec2 {
|
FlexRelativeVec2 {
|
||||||
main: None,
|
main: None,
|
||||||
|
@ -1883,26 +1931,9 @@ impl FlexItemBox {
|
||||||
cross_axis_is_item_block_axis,
|
cross_axis_is_item_block_axis,
|
||||||
content_box_size,
|
content_box_size,
|
||||||
padding_border,
|
padding_border,
|
||||||
|_| {
|
block_content_size_callback,
|
||||||
unreachable!(
|
|
||||||
"Unexpected block size query during row flex intrinsic size calculation."
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Compute the min-content and max-content contributions of the item.
|
|
||||||
// <https://drafts.csswg.org/css-flexbox/#intrinsic-item-contributions>
|
|
||||||
assert_eq!(
|
|
||||||
flex_axis,
|
|
||||||
FlexAxis::Row,
|
|
||||||
"The main axis should be the inline one"
|
|
||||||
);
|
|
||||||
let content_contribution_sizes = self
|
|
||||||
.independent_formatting_context
|
|
||||||
.outer_inline_content_sizes(layout_context, container_writing_mode, || {
|
|
||||||
automatic_min_size
|
|
||||||
});
|
|
||||||
|
|
||||||
let outer_flex_base_size = flex_base_size + pbm_auto_is_zero.main;
|
let outer_flex_base_size = flex_base_size + pbm_auto_is_zero.main;
|
||||||
let max_flex_factors = self.desired_flex_factors_for_preferred_width(
|
let max_flex_factors = self.desired_flex_factors_for_preferred_width(
|
||||||
content_contribution_sizes.max_content,
|
content_contribution_sizes.max_content,
|
||||||
|
@ -2097,7 +2128,7 @@ impl FlexItemBox {
|
||||||
content_box_size: FlexRelativeVec2<AuOrAuto>,
|
content_box_size: FlexRelativeVec2<AuOrAuto>,
|
||||||
padding_border_sums: FlexRelativeVec2<Au>,
|
padding_border_sums: FlexRelativeVec2<Au>,
|
||||||
block_content_size_callback: impl FnOnce(&mut FlexItemBox) -> Au,
|
block_content_size_callback: impl FnOnce(&mut FlexItemBox) -> Au,
|
||||||
) -> Au {
|
) -> (Au, bool) {
|
||||||
let flex_item = &mut self.independent_formatting_context;
|
let flex_item = &mut self.independent_formatting_context;
|
||||||
|
|
||||||
let used_flex_basis = match &flex_item.style().get_position().flex_basis {
|
let used_flex_basis = match &flex_item.style().get_position().flex_basis {
|
||||||
|
@ -2153,7 +2184,7 @@ impl FlexItemBox {
|
||||||
match used_flex_basis {
|
match used_flex_basis {
|
||||||
FlexBasis::Size(length) => {
|
FlexBasis::Size(length) => {
|
||||||
// > A. If the item has a definite used flex basis, that’s the flex base size.
|
// > A. If the item has a definite used flex basis, that’s the flex base size.
|
||||||
length
|
(length, true)
|
||||||
},
|
},
|
||||||
FlexBasis::Content => {
|
FlexBasis::Content => {
|
||||||
// FIXME: implement cases B, C, D.
|
// FIXME: implement cases B, C, D.
|
||||||
|
@ -2164,13 +2195,14 @@ impl FlexItemBox {
|
||||||
// > it has a preferred aspect ratio) and the flex item’s cross size is auto and not definite,
|
// > it has a preferred aspect ratio) and the flex item’s cross size is auto and not definite,
|
||||||
// > in this calculation use fit-content as the flex item’s cross size. The flex base size is
|
// > in this calculation use fit-content as the flex item’s cross size. The flex base size is
|
||||||
// > the item’s resulting main size.
|
// > the item’s resulting main size.
|
||||||
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.
|
||||||
flex_item.inline_content_sizes(layout_context).max_content
|
flex_item.inline_content_sizes(layout_context).max_content
|
||||||
} else {
|
} else {
|
||||||
block_content_size_callback(self)
|
block_content_size_callback(self)
|
||||||
}
|
};
|
||||||
|
(flex_basis, false)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2182,6 +2214,7 @@ impl FlexItemBox {
|
||||||
content_box_size: LogicalVec2<AuOrAuto>,
|
content_box_size: LogicalVec2<AuOrAuto>,
|
||||||
min_size: LogicalVec2<Au>,
|
min_size: LogicalVec2<Au>,
|
||||||
max_size: LogicalVec2<Option<Au>>,
|
max_size: LogicalVec2<Option<Au>>,
|
||||||
|
intrinsic_sizing_mode: IntrinsicSizingMode,
|
||||||
) -> Au {
|
) -> Au {
|
||||||
let mut positioning_context = PositioningContext::new_for_subtree(
|
let mut positioning_context = PositioningContext::new_for_subtree(
|
||||||
flex_context
|
flex_context
|
||||||
|
@ -2191,6 +2224,7 @@ 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.
|
||||||
let size = replaced.contents.used_size_as_if_inline_element(
|
let size = replaced.contents.used_size_as_if_inline_element(
|
||||||
flex_context.containing_block,
|
flex_context.containing_block,
|
||||||
&replaced.style,
|
&replaced.style,
|
||||||
|
@ -2232,15 +2266,29 @@ impl FlexItemBox {
|
||||||
block_size: AuOrAuto::Auto,
|
block_size: AuOrAuto::Auto,
|
||||||
style: &non_replaced.style,
|
style: &non_replaced.style,
|
||||||
};
|
};
|
||||||
let IndependentLayout {
|
let mut content_block_size = || {
|
||||||
content_block_size, ..
|
non_replaced
|
||||||
} = non_replaced.layout(
|
.layout(
|
||||||
flex_context.layout_context,
|
flex_context.layout_context,
|
||||||
&mut positioning_context,
|
&mut positioning_context,
|
||||||
&item_as_containing_block,
|
&item_as_containing_block,
|
||||||
flex_context.containing_block,
|
flex_context.containing_block,
|
||||||
);
|
)
|
||||||
content_block_size
|
.content_block_size
|
||||||
|
};
|
||||||
|
match intrinsic_sizing_mode {
|
||||||
|
IntrinsicSizingMode::Contribution => {
|
||||||
|
let inner_block_size = content_box_size
|
||||||
|
.block
|
||||||
|
.auto_is(content_block_size)
|
||||||
|
.clamp_between_extremums(min_size.block, max_size.block);
|
||||||
|
inner_block_size +
|
||||||
|
padding_border_margin.padding_border_sums.block +
|
||||||
|
padding_border_margin.margin.block_start.auto_is(Au::zero) +
|
||||||
|
padding_border_margin.margin.block_end.auto_is(Au::zero)
|
||||||
|
},
|
||||||
|
IntrinsicSizingMode::Size => content_block_size(),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,22 @@ use style::Zero;
|
||||||
|
|
||||||
use crate::style_ext::{Clamp, ComputedValuesExt};
|
use crate::style_ext::{Clamp, ComputedValuesExt};
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub(crate) enum IntrinsicSizingMode {
|
||||||
|
/// Used to refer to a min-content contribution or max-content contribution.
|
||||||
|
/// This is the size that a box contributes to its containing block’s min-content
|
||||||
|
/// or max-content size. Note this is based on the outer size of the box,
|
||||||
|
/// and takes into account the relevant sizing properties of the element.
|
||||||
|
/// <https://drafts.csswg.org/css-sizing-3/#contributions>
|
||||||
|
Contribution,
|
||||||
|
/// Used to refer to a min-content size or max-content size.
|
||||||
|
/// This is the size based on the contents of an element, without regard for its context.
|
||||||
|
/// Note this is usually based on the inner (content-box) size of the box,
|
||||||
|
/// and ignores the relevant sizing properties of the element.
|
||||||
|
/// <https://drafts.csswg.org/css-sizing-3/#intrinsic>
|
||||||
|
Size,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
#[derive(Clone, Copy, Debug, Default, Serialize)]
|
||||||
pub(crate) struct ContentSizes {
|
pub(crate) struct ContentSizes {
|
||||||
pub min_content: Au,
|
pub min_content: Au,
|
||||||
|
|
2
tests/wpt/meta/MANIFEST.json
vendored
2
tests/wpt/meta/MANIFEST.json
vendored
|
@ -545450,7 +545450,7 @@
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"flex-one-sets-flex-basis-to-zero-px.html": [
|
"flex-one-sets-flex-basis-to-zero-px.html": [
|
||||||
"8fca136352ff7d9a838616d73f809da7cff44ba0",
|
"d7116868d7512efc8112bf5052c30a4dd5eea35d",
|
||||||
[
|
[
|
||||||
null,
|
null,
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[align-content-wrap-004.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[auto-height-column-with-border-and-padding.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[auto-height-with-flex.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[box-sizing-001.html]
|
|
||||||
[.flexbox 7]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[box-sizing-min-max-sizes-001.html]
|
|
||||||
[.flexbox 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[change-column-flex-width.html]
|
|
||||||
[#container 1]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[column-flex-child-with-overflow-scroll.html]
|
|
||||||
[.flexbox 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.flexbox 2]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[column-reverse-gap.html]
|
|
||||||
[.flexbox 1]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-basis-012.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flex-column-relayout-assert.html]
|
|
||||||
[.flexbox 1]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flex-direction-column-overlap-001.html]
|
|
||||||
[#container 1]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-direction-column-reverse.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-direction-column.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-direction-with-element-insert.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-direction.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-height-min-content.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-minimum-height-flex-items-013.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,13 +0,0 @@
|
||||||
[flex-minimum-height-flex-items-025.html]
|
|
||||||
[.outer-column-flexbox > div 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.outer-column-flexbox > div 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.outer-column-flexbox > div 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.outer-column-flexbox > div 4]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,12 +1,27 @@
|
||||||
[flex-one-sets-flex-basis-to-zero-px.html]
|
[flex-one-sets-flex-basis-to-zero-px.html]
|
||||||
[.flexbox 4]
|
[.flexbox 10]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.flexbox 5]
|
[.flexbox 11]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.flexbox 6]
|
[.flexbox 12]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.flexbox 2]
|
[.flexbox 13]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.flexbox 14]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.flexbox 15]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.flexbox 16]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.flexbox 17]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[.flexbox 18]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flex-outer-flexbox-column-recalculate-height-on-resize-001.html]
|
|
||||||
[.OuterFlexbox 1]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox-definite-sizes-006.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox_align-items-center-3.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox_direction-column-reverse.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox_direction-column.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[gap-014.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,4 +0,0 @@
|
||||||
[gap-017.html]
|
|
||||||
[.button 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[order-with-column-reverse.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[overflow-auto-008.html]
|
|
||||||
[hbox dimensions]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[percentage-heights-005.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[percentage-heights-008.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[stretching-orthogonal-flows.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[table-as-item-change-cell.html]
|
|
||||||
expected: FAIL
|
|
|
@ -2,6 +2,7 @@
|
||||||
<html>
|
<html>
|
||||||
<title>CSS Flexbox: flex-basis with zero pixel</title>
|
<title>CSS Flexbox: flex-basis with zero pixel</title>
|
||||||
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#flex-basis-property">
|
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#flex-basis-property">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#intrinsic-main-sizes">
|
||||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||||
<link href="support/flexbox.css" rel="stylesheet">
|
<link href="support/flexbox.css" rel="stylesheet">
|
||||||
<meta name="assert" content="This test ensures that setting 'flex-basis' property to
|
<meta name="assert" content="This test ensures that setting 'flex-basis' property to
|
||||||
|
@ -10,18 +11,40 @@ and 'writing-mode' value works properly.">
|
||||||
<style>
|
<style>
|
||||||
.flexbox > div {
|
.flexbox > div {
|
||||||
font: 14px/1 Ahem;
|
font: 14px/1 Ahem;
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-zero {
|
||||||
|
flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-zero-one-zero-percent {
|
||||||
|
flex: 0 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-zero-one-zero-px {
|
||||||
|
flex: 0 1 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-half {
|
||||||
|
flex: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-half-one-zero-percent {
|
||||||
|
flex: 0.5 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-half-one-zero-px {
|
||||||
|
flex: 0.5 1 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-one-one-zero-percent {
|
.flex-one-one-zero-percent {
|
||||||
flex: 1 1 0%;
|
flex: 1 1 0%;
|
||||||
min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-one-one-zero-px {
|
.flex-one-one-zero-px {
|
||||||
flex: 1 1 0px;
|
flex: 1 1 0px;
|
||||||
min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vertical {
|
.vertical {
|
||||||
|
@ -33,6 +56,35 @@ and 'writing-mode' value works properly.">
|
||||||
<script src="/resources/check-layout-th.js"></script>
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
<body onload="document.fonts.ready.then(() => { checkLayout('.flexbox'); })">
|
<body onload="document.fonts.ready.then(() => { checkLayout('.flexbox'); })">
|
||||||
<div id=log></div>
|
<div id=log></div>
|
||||||
|
<div class="flexbox column">
|
||||||
|
<div class="flex-zero" data-expected-height="14">Flex item with flex: 0</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column">
|
||||||
|
<div class="flex-zero-one-zero-percent" data-expected-height="14">Flex item with flex: 0 1 0%</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column">
|
||||||
|
<div class="flex-zero-one-zero-px" data-expected-height="0">Flex item with flex: 0 1 0px</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column">
|
||||||
|
<div class="flex-half" data-expected-height="14">Flex item with flex: 0.5</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column">
|
||||||
|
<div class="flex-half-one-zero-percent" data-expected-height="14">Flex item with flex: 0.5 1 0%</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- A flex-grow of 0 would size the container to the flex base size of the item (0px),
|
||||||
|
and a flex-grow of 1 would size it to the max-content contribution of the item (14px).
|
||||||
|
Therefore, a flew-grow of 0.5 sizes the container to the average, 7px.
|
||||||
|
And then the item grows to fill half of that, 3.5px.
|
||||||
|
Note that Gecko, Blink and WebKit use the flex-basis instead. -->
|
||||||
|
<div class="flexbox column">
|
||||||
|
<div class="flex-half-one-zero-px" data-expected-height="4">Flex item with flex: 0.5 1 0px</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flexbox column">
|
<div class="flexbox column">
|
||||||
<div class="flex-one" data-expected-height="14">Flex item with flex: 1</div>
|
<div class="flex-one" data-expected-height="14">Flex item with flex: 1</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,8 +93,39 @@ and 'writing-mode' value works properly.">
|
||||||
<div class="flex-one-one-zero-percent" data-expected-height="14">Flex item with flex: 1 1 0%</div>
|
<div class="flex-one-one-zero-percent" data-expected-height="14">Flex item with flex: 1 1 0%</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- flex-grow is >= 1, so the flex container is sized to the max-content contribution of the item.
|
||||||
|
Note that Gecko, Blink and WebKit use the flex-basis instead. -->
|
||||||
<div class="flexbox column">
|
<div class="flexbox column">
|
||||||
<div class="flex-one-one-zero-px" data-expected-height="0">Flex item with flex: 1 1 0px</div>
|
<div class="flex-one-one-zero-px" data-expected-height="14">Flex item with flex: 1 1 0px</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column vertical">
|
||||||
|
<div class="flex-zero" data-expected-width="14">Flex item with flex: 0</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column vertical">
|
||||||
|
<div class="flex-zero-one-zero-percent" data-expected-width="14">Flex item with flex: 0 1 0%</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column vertical">
|
||||||
|
<div class="flex-zero-one-zero-px" data-expected-width="0">Flex item with flex: 0 1 0px</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column vertical">
|
||||||
|
<div class="flex-half" data-expected-width="14">Flex item with flex: 0.5</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox column vertical">
|
||||||
|
<div class="flex-half-one-zero-percent" data-expected-width="14">Flex item with flex: 0.5 1 0%</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- A flex-grow of 0 would size the container to the flex base size of the item (0px),
|
||||||
|
and a flex-grow of 1 would size it to the max-content contribution of the item (14px).
|
||||||
|
Therefore, a flew-grow of 0.5 sizes the container to the average, 7px.
|
||||||
|
And then the item grows to fill half of that, 3.5px.
|
||||||
|
Note that Gecko, Blink and WebKit use the flex-basis instead. -->
|
||||||
|
<div class="flexbox column vertical">
|
||||||
|
<div class="flex-half-one-zero-px" data-expected-width="4">Flex item with flex: 0.5 1 0px</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flexbox column vertical">
|
<div class="flexbox column vertical">
|
||||||
|
@ -53,8 +136,10 @@ and 'writing-mode' value works properly.">
|
||||||
<div class="flex-one-one-zero-percent" data-expected-width="14">Flex item with flex: 1 1 0%</div>
|
<div class="flex-one-one-zero-percent" data-expected-width="14">Flex item with flex: 1 1 0%</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- flex-grow is >= 1, so the flex container is sized to the max-content contribution of the item.
|
||||||
|
Note that Gecko, Blink and WebKit use the flex-basis instead. -->
|
||||||
<div class="flexbox column vertical">
|
<div class="flexbox column vertical">
|
||||||
<div class="flex-one-one-zero-px" data-expected-width="0">Flex item with flex: 1 1 0px</div>
|
<div class="flex-one-one-zero-px" data-expected-width="14">Flex item with flex: 1 1 0px</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue