Skip to content

Commit 3741d30

Browse files
committed
LibWeb: Support percentage values in min/max flex item size constraints
Originally, 7200b3a introduced a two-pass system to determine hypothetical cross sizes. Later, this was partially reverted in 0084d99, but some code was left behind that caused resolution of percentages in `{min/max}-{width/height}` size constraints not to work. Through intrinsic sizing, we can potentially end up with a definite available space for the items in the last FC run. At that point we should be able to resolve percentages against the available space, but we were never doing that.
1 parent 4ff17fc commit 3741d30

File tree

5 files changed

+47
-24
lines changed

5 files changed

+47
-24
lines changed

Libraries/LibWeb/Layout/FlexFormattingContext.cpp

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,8 @@ void FlexFormattingContext::run(AvailableSpace const& available_space)
155155

156156
// Cross Size Determination
157157
// 7. Determine the hypothetical cross size of each item
158-
for (auto& item : m_flex_items) {
159-
determine_hypothetical_cross_size_of_item(item, false);
160-
}
158+
for (auto& item : m_flex_items)
159+
determine_hypothetical_cross_size_of_item(item);
161160

162161
// 8. Calculate the cross size of each flex line.
163162
calculate_cross_size_of_each_flex_line();
@@ -1133,27 +1132,19 @@ void FlexFormattingContext::resolve_flexible_lengths()
11331132
}
11341133
}
11351134

1136-
// https://www.w3.org/TR/css-flexbox-1/#hypothetical-cross-size
1137-
void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& item, bool resolve_percentage_min_max_sizes)
1135+
// https://drafts.csswg.org/css-flexbox/#hypothetical-cross-size
1136+
void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& item)
11381137
{
1139-
// Determine the hypothetical cross size of each item by performing layout
1140-
// as if it were an in-flow block-level box with the used main size
1141-
// and the given available space, treating auto as fit-content.
1138+
// Determine the hypothetical cross size of each item by performing layout as if it were an in-flow block-level box
1139+
// with the used main size and the given available space, treating auto as fit-content.
11421140

11431141
auto const& computed_min_size = this->computed_cross_min_size(item.box);
1144-
auto const& computed_max_size = this->computed_cross_max_size(item.box);
11451142

1146-
auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item) : 0;
1147-
auto clamp_max = (!should_treat_cross_max_size_as_none(item.box) && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item) : CSSPixels::max();
1143+
auto clamp_min = computed_min_size.is_auto() ? 0 : specified_cross_min_size(item);
1144+
auto clamp_max = should_treat_cross_max_size_as_none(item.box) ? CSSPixels::max() : specified_cross_max_size(item);
11481145

11491146
// If we have a definite cross size, this is easy! No need to perform layout, we can just use it as-is.
11501147
if (has_definite_cross_size(item)) {
1151-
// To avoid subtracting padding and border twice for `box-sizing: border-box` only min and max clamp should happen on a second pass
1152-
if (resolve_percentage_min_max_sizes) {
1153-
item.hypothetical_cross_size = css_clamp(item.hypothetical_cross_size, clamp_min, clamp_max);
1154-
return;
1155-
}
1156-
11571148
item.hypothetical_cross_size = css_clamp(inner_cross_size(item), clamp_min, clamp_max);
11581149
return;
11591150
}
@@ -1946,9 +1937,8 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_cross_size_of_flex_containe
19461937
// https://drafts.csswg.org/css-flexbox-1/#intrinsic-item-contributions
19471938
CSSPixels FlexFormattingContext::calculate_main_min_content_contribution(FlexItem const& item) const
19481939
{
1949-
// The main-size min-content contribution of a flex item is
1950-
// the larger of its outer min-content size and outer preferred size if that is not auto,
1951-
// clamped by its min/max main size.
1940+
// The main-size min-content contribution of a flex item is the larger of its outer min-content size and outer
1941+
// preferred size if that is not auto, clamped by its min/max main size.
19521942
auto larger_size = [&] {
19531943
auto inner_min_content_size = calculate_min_content_main_size(item);
19541944
if (computed_main_size(item.box).is_auto())

Libraries/LibWeb/Layout/FlexFormattingContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class FlexFormattingContext final : public FormattingContext {
184184

185185
void resolve_cross_axis_auto_margins();
186186

187-
void determine_hypothetical_cross_size_of_item(FlexItem&, bool resolve_percentage_min_max_sizes);
187+
void determine_hypothetical_cross_size_of_item(FlexItem&);
188188

189189
void calculate_cross_size_of_each_flex_line();
190190

Libraries/LibWeb/Layout/FormattingContext.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ class FormattingContext {
3838

3939
virtual void run(AvailableSpace const&) = 0;
4040

41-
// This function returns the automatic content height of the context's root box.
41+
// These functions return the automatic content dimensions of the context's root box.
4242
virtual CSSPixels automatic_content_width() const = 0;
43-
44-
// This function returns the automatic content height of the context's root box.
4543
virtual CSSPixels automatic_content_height() const = 0;
4644

4745
Box const& context_box() const { return m_context_box; }
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not-inline
2+
BlockContainer <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 41 0+0+0] [BFC] children: not-inline
3+
BlockContainer <body> at [8,8] [8+0+0 784 0+0+8] [8+0+0 25 0+0+8] children: not-inline
4+
Box <div.a> at [8,8] flex-container(column) [0+0+0 784 0+0+0] [0+0+0 25 0+0+0] [FFC] children: not-inline
5+
BlockContainer <div.b> at [8,8] flex-item [0+0+0 784 0+0+0] [0+0+0 25 0+0+0] [BFC] children: not-inline
6+
BlockContainer <div.c> at [8,8] [0+0+0 50 0+0+734] [0+0+0 25 0+0+0] children: inline
7+
TextNode <#text> (not painted)
8+
9+
ViewportPaintable (Viewport<#document>) [0,0 800x600]
10+
PaintableWithLines (BlockContainer<HTML>) [0,0 800x41]
11+
PaintableWithLines (BlockContainer<BODY>) [8,8 784x25]
12+
PaintableBox (Box<DIV>.a) [8,8 784x25]
13+
PaintableWithLines (BlockContainer<DIV>.b) [8,8 784x25]
14+
PaintableWithLines (BlockContainer<DIV>.c) [8,8 50x25]
15+
16+
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
17+
SC for BlockContainer<HTML> [0,0 800x41] [children: 0] (z-index: auto)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<style>
3+
.a {
4+
display: flex;
5+
flex-direction: column;
6+
align-items: center;
7+
}
8+
.b {
9+
background: blue;
10+
min-width: 100%;
11+
}
12+
.c {
13+
background: red;
14+
height: 25px;
15+
width: 50px;
16+
}
17+
</style>
18+
<div class="a"><div class="b"><div class="c">

0 commit comments

Comments
 (0)