LibWeb: Support flex-basis: calc(...)

1. Propagate calc() values from StyleProperties to ComputedValues.
2. Actually resolve calc() values when determining the used flex basis.

This makes the "support" section on https://shopify.com/ show up
correctly as a 2x2 grid (instead of 1x4). :^)
This commit is contained in:
Andreas Kling 2023-05-16 16:59:47 +02:00
parent e81d4ca1ac
commit 2e13f65ff4
Notes: sideshowbarker 2024-07-17 02:14:39 +09:00
4 changed files with 59 additions and 4 deletions

View File

@ -0,0 +1,24 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (1,1) content-size 798x80 [BFC] children: not-inline
BlockContainer <body> at (10,10) content-size 780x62 children: not-inline
Box <div.flex-container> at (11,11) content-size 778x60 flex-container(row) [FFC] children: not-inline
BlockContainer <div.flex-item> at (12,12) content-size 386x28 flex-item [BFC] children: inline
line 0 width: 58.398437, height: 21.835937, bottom: 21.835937, baseline: 16.914062
frag 0 from TextNode start: 0, length: 6, rect: [12,12 58.398437x21.835937]
"Item 1"
TextNode <#text>
BlockContainer <div.flex-item> at (401,12) content-size 386x28 flex-item [BFC] children: inline
line 0 width: 61.484375, height: 21.835937, bottom: 21.835937, baseline: 16.914062
frag 0 from TextNode start: 0, length: 6, rect: [401,12 61.484375x21.835937]
"Item 2"
TextNode <#text>
BlockContainer <div.flex-item> at (12,42) content-size 386x28 flex-item [BFC] children: inline
line 0 width: 61.835937, height: 21.835937, bottom: 21.835937, baseline: 16.914062
frag 0 from TextNode start: 0, length: 6, rect: [12,42 61.835937x21.835937]
"Item 3"
TextNode <#text>
BlockContainer <div.flex-item> at (401,42) content-size 386x28 flex-item [BFC] children: inline
line 0 width: 60.15625, height: 21.835937, bottom: 21.835937, baseline: 16.914062
frag 0 from TextNode start: 0, length: 6, rect: [401,42 60.15625x21.835937]
"Item 4"
TextNode <#text>

View File

@ -0,0 +1,18 @@
<!doctype html><style>
* {
border: 1px solid black;
box-sizing: border-box;
font: 20px SerenitySans;
}
.flex-container {
display: flex;
flex-wrap: wrap;
background: pink;
column-gap: 1px;
}
.flex-item {
flex-basis: calc(50% - 1px);
background: orange;
height: 30px;
}
</style><div class="flex-container"><div class="flex-item">Item 1</div><div class="flex-item">Item 2</div><div class="flex-item">Item 3</div><div class="flex-item">Item 4</div></div>

View File

@ -294,6 +294,9 @@ Optional<CSS::FlexBasisData> StyleProperties::flex_basis() const
if (value->has_length())
return { { CSS::FlexBasis::LengthPercentage, value->to_length() } };
if (value->is_calculated())
return { { CSS::FlexBasis::LengthPercentage, CSS::LengthPercentage { value->as_calculated() } } };
return {};
}

View File

@ -34,6 +34,8 @@ static CSS::Size to_css_size(CSS::LengthPercentage const& length_percentage)
return CSS::Size::make_auto();
if (length_percentage.is_length())
return CSS::Size::make_length(length_percentage.length());
if (length_percentage.is_calculated())
return CSS::Size::make_calculated(length_percentage.calculated());
return CSS::Size::make_percentage(length_percentage.percentage());
}
@ -612,13 +614,21 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
return false;
if (flex_basis.length_percentage->is_length())
return true;
bool can_resolve_percentages = is_row_layout()
? m_flex_container_state.has_definite_width()
: m_flex_container_state.has_definite_height();
if (flex_basis.length_percentage->is_calculated()) {
// FIXME: Handle calc() in used flex basis.
auto const& calc_value = *flex_basis.length_percentage->calculated();
if (calc_value.resolves_to_length())
return true;
if (calc_value.resolves_to_percentage() || (calc_value.resolves_to_length() && calc_value.contains_percentage()))
return can_resolve_percentages;
return false;
}
if (is_row_layout())
return m_flex_container_state.has_definite_width();
return m_flex_container_state.has_definite_height();
VERIFY(flex_basis.length_percentage->is_percentage());
return can_resolve_percentages;
}(item.used_flex_basis);
// A. If the item has a definite used flex basis, thats the flex base size.