Skip to content

Commit

Permalink
Fixes for content alignment spec updates (#635)
Browse files Browse the repository at this point in the history
* Update gentests to match Chrome 123

* Implement content alignment fixes to align with spec changes

* Update changelog

* Fix clippy lints
  • Loading branch information
nicoburns authored May 13, 2024
1 parent 5edada7 commit 04e20d1
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 92 deletions.
6 changes: 6 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release Notes

## 0.4.4

### Fixes

- Content alignment (`align-content`/`justify-content`) behaviour was updated to match the latest spec (and Chrome 123+) (#635)

## 0.4.3

### Fixes
Expand Down
32 changes: 32 additions & 0 deletions src/compute/common/alignment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
//! Generic CSS alignment code that is shared between both the Flexbox and CSS Grid algorithms.
use crate::style::AlignContent;

/// Implement fallback alignment.
///
/// In addition to the spec at https://www.w3.org/TR/css-align-3/ this implementation follows
/// the resolution of https://github.com/w3c/csswg-drafts/issues/10154
pub(crate) fn apply_alignment_fallback(
free_space: f32,
num_items: usize,
mut alignment_mode: AlignContent,
mut is_safe: bool,
) -> AlignContent {
// Fallback occurs in two cases:

// 1. If there is only a single item being aligned and alignment is a distributed alignment keyword
// https://www.w3.org/TR/css-align-3/#distribution-values
if num_items <= 1 || free_space <= 0.0 {
(alignment_mode, is_safe) = match alignment_mode {
AlignContent::Stretch => (AlignContent::FlexStart, true),
AlignContent::SpaceBetween => (AlignContent::FlexStart, true),
AlignContent::SpaceAround => (AlignContent::Center, true),
AlignContent::SpaceEvenly => (AlignContent::Center, true),
_ => (alignment_mode, is_safe),
}
};

// 2. If free space is negative the "safe" alignment variants all fallback to Start alignment
if free_space <= 0.0 && is_safe {
alignment_mode = AlignContent::Start;
}

alignment_mode
}

/// Generic alignment function that is used:
/// - For both align-content and justify-content alignment
/// - For both the Flexbox and CSS Grid algorithms
Expand Down
10 changes: 8 additions & 2 deletions src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::util::sys::{f32_max, new_vec_with_capacity, Vec};
use crate::util::MaybeMath;
use crate::util::{MaybeResolve, ResolveOrZero};

use super::common::alignment::apply_alignment_fallback;
#[cfg(feature = "content_size")]
use super::common::content_size::compute_content_size_contribution;

Expand Down Expand Up @@ -1539,7 +1540,10 @@ fn distribute_remaining_free_space(flex_lines: &mut [FlexLine], constants: &Algo
let num_items = line.items.len();
let layout_reverse = constants.dir.is_reverse();
let gap = constants.gap.main(constants.dir);
let justify_content_mode = constants.justify_content.unwrap_or(JustifyContent::FlexStart);
let is_safe = false; // TODO: Implement safe alignment
let raw_justify_content_mode = constants.justify_content.unwrap_or(JustifyContent::FlexStart);
let justify_content_mode =
apply_alignment_fallback(free_space, num_items, raw_justify_content_mode, is_safe);

let justify_item = |(i, child): (usize, &mut FlexItem)| {
child.offset_main =
Expand Down Expand Up @@ -1703,9 +1707,11 @@ fn determine_container_cross_size(
fn align_flex_lines_per_align_content(flex_lines: &mut [FlexLine], constants: &AlgoConstants, total_cross_size: f32) {
let num_lines = flex_lines.len();
let gap = constants.gap.cross(constants.dir);
let align_content_mode = constants.align_content;
let total_cross_axis_gap = sum_axis_gaps(gap, num_lines);
let free_space = constants.inner_container_size.cross(constants.dir) - total_cross_size - total_cross_axis_gap;
let is_safe = false; // TODO: Implement safe alignment

let align_content_mode = apply_alignment_fallback(free_space, num_lines, constants.align_content, is_safe);

let align_line = |(i, line): (usize, &mut FlexLine)| {
line.offset_cross =
Expand Down
6 changes: 4 additions & 2 deletions src/compute/grid/alignment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Alignment of tracks and final positioning of items
use super::types::GridTrack;
use crate::compute::common::alignment::compute_alignment_offset;
use crate::compute::common::alignment::{apply_alignment_fallback, compute_alignment_offset};
use crate::geometry::{InBothAbsAxis, Line, Point, Rect, Size};
use crate::style::{AlignContent, AlignItems, AlignSelf, AvailableSpace, Overflow, Position};
use crate::tree::{Layout, LayoutPartialTree, LayoutPartialTreeExt, NodeId, SizingMode};
Expand Down Expand Up @@ -31,6 +31,8 @@ pub(super) fn align_tracks(
// simply pass zero here. Grid layout is never reversed.
let gap = 0.0;
let layout_is_reversed = false;
let is_safe = false; // TODO: Implement safe alignment
let track_alignment = apply_alignment_fallback(free_space, num_tracks, track_alignment_style, is_safe);

// Compute offsets
let mut total_offset = origin;
Expand All @@ -44,7 +46,7 @@ pub(super) fn align_tracks(
let offset = if is_gutter {
0.0
} else {
compute_alignment_offset(free_space, num_tracks, gap, track_alignment_style, layout_is_reversed, is_first)
compute_alignment_offset(free_space, num_tracks, gap, track_alignment, layout_is_reversed, is_first)
};

track.offset = total_offset + offset;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tests/generated/flex/bevy_issue_10343_block.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tests/generated/flex/bevy_issue_10343_flex.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tests/generated/flex/bevy_issue_10343_grid.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 04e20d1

Please sign in to comment.