mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 10:07:44 +00:00
LibWeb: Mark flex item cross sizes as definite when spec asks us to
The CSS-FLEXBOX-1 spec gives us two situations in which flex item cross sizes should be considered definite. Both of them happen *during* flex layout, which is super finicky but it is what it is.
This commit is contained in:
parent
83bb16ede3
commit
60ac258a48
2 changed files with 46 additions and 0 deletions
|
@ -61,6 +61,26 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode layout_mode)
|
||||||
// 1. Generate anonymous flex items
|
// 1. Generate anonymous flex items
|
||||||
generate_anonymous_flex_items();
|
generate_anonymous_flex_items();
|
||||||
|
|
||||||
|
{
|
||||||
|
// https://drafts.csswg.org/css-flexbox-1/#definite-sizes
|
||||||
|
// 3. 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 container’s inner cross size
|
||||||
|
// (clamped to the flex item’s min and max cross size) and is considered definite.
|
||||||
|
if (is_single_line() && has_definite_cross_size(flex_container())) {
|
||||||
|
auto flex_container_inner_cross_size = specified_cross_size(flex_container());
|
||||||
|
for (auto& item : m_flex_items) {
|
||||||
|
if (!flex_item_is_stretched(item))
|
||||||
|
continue;
|
||||||
|
auto item_min_cross_size = has_cross_min_size(item.box) ? specified_cross_min_size(item.box) : automatic_minimum_size(item);
|
||||||
|
auto item_max_cross_size = has_cross_max_size(item.box) ? specified_cross_max_size(item.box) : INFINITY;
|
||||||
|
auto item_preferred_outer_cross_size = css_clamp(flex_container_inner_cross_size, item_min_cross_size, item_max_cross_size);
|
||||||
|
auto item_inner_cross_size = item_preferred_outer_cross_size - item.margins.cross_before - item.margins.cross_after - item.padding.cross_before - item.padding.cross_after - item.borders.cross_before - item.borders.cross_after;
|
||||||
|
set_cross_size(item.box, item_inner_cross_size);
|
||||||
|
set_has_definite_cross_size(item.box, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Determine the available main and cross space for the flex items
|
// 2. Determine the available main and cross space for the flex items
|
||||||
float main_max_size = NumericLimits<float>::max();
|
float main_max_size = NumericLimits<float>::max();
|
||||||
float main_min_size = 0;
|
float main_min_size = 0;
|
||||||
|
@ -143,6 +163,19 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode layout_mode)
|
||||||
// 15. Determine the flex container’s used cross size:
|
// 15. Determine the flex container’s used cross size:
|
||||||
determine_flex_container_used_cross_size(cross_min_size, cross_max_size);
|
determine_flex_container_used_cross_size(cross_min_size, cross_max_size);
|
||||||
|
|
||||||
|
{
|
||||||
|
// https://drafts.csswg.org/css-flexbox-1/#definite-sizes
|
||||||
|
// 4. Once the cross size of a flex line has been determined,
|
||||||
|
// the cross sizes of items in auto-sized flex containers are also considered definite for the purpose of layout.
|
||||||
|
auto const& flex_container_computed_cross_size = is_row_layout() ? flex_container().computed_values().height() : flex_container().computed_values().width();
|
||||||
|
if (flex_container_computed_cross_size.is_auto()) {
|
||||||
|
for (auto& item : m_flex_items) {
|
||||||
|
set_cross_size(item.box, item.cross_size);
|
||||||
|
set_has_definite_cross_size(item.box, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 16. Align all flex lines (per align-content)
|
// 16. Align all flex lines (per align-content)
|
||||||
align_all_flex_lines();
|
align_all_flex_lines();
|
||||||
|
|
||||||
|
@ -1664,4 +1697,15 @@ SizeConstraint FlexFormattingContext::flex_container_cross_constraint() const
|
||||||
return is_row_layout() ? m_flex_container_state.height_constraint : m_flex_container_state.width_constraint;
|
return is_row_layout() ? m_flex_container_state.height_constraint : m_flex_container_state.width_constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-flexbox-1/#stretched
|
||||||
|
bool FlexFormattingContext::flex_item_is_stretched(FlexItem const& item) const
|
||||||
|
{
|
||||||
|
auto alignment = alignment_for_item(item);
|
||||||
|
if (alignment != CSS::AlignItems::Stretch)
|
||||||
|
return false;
|
||||||
|
// If the cross size property of the flex item computes to auto, and neither of the cross-axis margins are auto, the flex item is stretched.
|
||||||
|
auto const& computed_cross_size = is_row_layout() ? item.box.computed_values().height() : item.box.computed_values().width();
|
||||||
|
return computed_cross_size.is_auto() && !item.margins.cross_before_is_auto && !item.margins.cross_after_is_auto;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ private:
|
||||||
Optional<float> transferred_size_suggestion(FlexItem const&) const;
|
Optional<float> transferred_size_suggestion(FlexItem const&) const;
|
||||||
float content_size_suggestion(FlexItem const&) const;
|
float content_size_suggestion(FlexItem const&) const;
|
||||||
|
|
||||||
|
bool flex_item_is_stretched(FlexItem const&) const;
|
||||||
|
|
||||||
void set_main_size(Box const&, float size);
|
void set_main_size(Box const&, float size);
|
||||||
void set_cross_size(Box const&, float size);
|
void set_cross_size(Box const&, float size);
|
||||||
void set_has_definite_main_size(Box const&, bool);
|
void set_has_definite_main_size(Box const&, bool);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue