Skip to content

Commit 1dc8683

Browse files
committed
Fix align content not stretch with align items stretch
1 parent 2d2da5e commit 1dc8683

9 files changed

+319
-11
lines changed

benches/generated/align_content_flex_end.rs

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benches/generated/align_content_not_stretch_with_align_items_stretch.rs

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benches/generated/mod.rs

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/compute/flexbox.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ struct AlgoConstants {
145145
gap: Size<f32>,
146146
/// The align_items property of this node
147147
align_items: AlignItems,
148+
/// The align_content property of this node
149+
align_content: AlignContent,
148150

149151
/// The content-box size of the node being laid out (if known)
150152
node_inner_size: Size<Option<f32>>,
@@ -318,7 +320,7 @@ fn compute_preliminary(
318320
// 9. Handle 'align-content: stretch'.
319321
#[cfg(feature = "debug")]
320322
NODE_LOGGER.log("handle_align_content_stretch");
321-
handle_align_content_stretch(tree, &mut flex_lines, node, known_dimensions, &constants);
323+
handle_align_content_stretch(&mut flex_lines, known_dimensions, &constants);
322324

323325
// 10. Collapse visibility:collapse items. If any flex items have visibility: collapse,
324326
// note the cross size of the line they’re in as the item’s strut size, and restart
@@ -438,6 +440,7 @@ fn compute_constants(
438440
let padding = style.padding.resolve_or_zero(parent_size.width);
439441
let border = style.border.resolve_or_zero(parent_size.width);
440442
let align_items = style.align_items.unwrap_or(crate::style::AlignItems::Stretch);
443+
let align_content = style.align_content.unwrap_or(crate::style::AlignContent::Stretch);
441444

442445
let padding_border = padding + border;
443446

@@ -469,6 +472,7 @@ fn compute_constants(
469472
gap,
470473
padding_border,
471474
align_items,
475+
align_content,
472476
node_inner_size,
473477
container_size,
474478
inner_container_size,
@@ -1130,7 +1134,15 @@ fn calculate_cross_size(
11301134
node_size: Size<Option<f32>>,
11311135
constants: &AlgoConstants,
11321136
) {
1133-
if flex_lines.len() == 1 && node_size.cross(constants.dir).is_some() {
1137+
// Note: AlignContent::SpaceEvenly and AlignContent::SpaceAround behave like AlignContent::Stretch when there is only
1138+
// a single flex line in the container. See: https://www.w3.org/TR/css-flexbox-1/#align-content-property
1139+
if flex_lines.len() == 1
1140+
&& node_size.cross(constants.dir).is_some()
1141+
&& matches!(
1142+
constants.align_content,
1143+
AlignContent::Stretch | AlignContent::SpaceEvenly | AlignContent::SpaceAround
1144+
)
1145+
{
11341146
flex_lines[0].cross_size =
11351147
(node_size.cross(constants.dir).maybe_sub(constants.padding_border.cross_axis_sum(constants.dir)))
11361148
.unwrap_or(0.0);
@@ -1176,15 +1188,8 @@ fn calculate_cross_size(
11761188
/// and the sum of the flex lines' cross sizes is less than the flex container’s inner cross size,
11771189
/// increase the cross size of each flex line by equal amounts such that the sum of their cross sizes exactly equals the flex container’s inner cross size.
11781190
#[inline]
1179-
fn handle_align_content_stretch(
1180-
tree: &mut impl LayoutTree,
1181-
flex_lines: &mut [FlexLine],
1182-
node: Node,
1183-
node_size: Size<Option<f32>>,
1184-
constants: &AlgoConstants,
1185-
) {
1186-
let align_content = tree.style(node).align_content.unwrap_or(AlignContent::Stretch);
1187-
if align_content == AlignContent::Stretch && node_size.cross(constants.dir).is_some() {
1191+
fn handle_align_content_stretch(flex_lines: &mut [FlexLine], node_size: Size<Option<f32>>, constants: &AlgoConstants) {
1192+
if constants.align_content == AlignContent::Stretch && node_size.cross(constants.dir).is_some() {
11881193
let total_cross_axis_gap = sum_axis_gaps(constants.gap.cross(constants.dir), flex_lines.len());
11891194
let total_cross: f32 = flex_lines.iter().map(|line| line.cross_size).sum::<f32>() + total_cross_axis_gap;
11901195
let inner_cross =

tests/generated/align_content_flex_end.rs

Lines changed: 101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/generated/align_content_not_stretch_with_align_items_stretch.rs

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)