[Masonry] Implement item-level baseline alignment [chromium/src : main]

0 views
Skip to first unread message

Alison Maher (Gerrit)

unread,
Jan 7, 2026, 5:28:03 PM (4 days ago) Jan 7
to Yanling Wang, Kurt Catti-Schmidt, Celeste Pan, Chromium LUCI CQ, chromium...@chromium.org, Javier Fernandez, blink-revi...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, zol...@webkit.org
Attention needed from Kurt Catti-Schmidt and Yanling Wang

Alison Maher added 23 comments

Patchset-level comments
File-level comment, Patchset 1 (Latest):
Alison Maher . resolved

Initial pass, haven't take a look at tests yet

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
Line 154, Patchset 1 (Latest): bool& must_create_baselines) const;
Alison Maher . unresolved

nit: maybe `needs_baseline` or `needs_baseline_calculation`

Line 154, Patchset 1 (Latest): bool& must_create_baselines) const;
Alison Maher . unresolved

Since this is an out pram, I' suggest updating the comment to note what it is and what it gets set to

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
Line 270, Patchset 1 (Latest):LayoutUnit TrackBaseline(const GridItemData& grid_lanes_item,
Alison Maher . unresolved

This one looks pretty much the same as https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.cc;l=790-807?q=grid_layout_algorithm.cc&ss=chromium

Could we move that one to grid_layout_utils and reuse that here instead? That way if one gets updated, it will work in both.

Line 365, Patchset 1 (Latest): // avoid mutating the state needed for final placement.
Alison Maher . unresolved

Where are things getting mutated? Can we just not mutate it if we are in the first pass?

Line 365, Patchset 1 (Latest): // avoid mutating the state needed for final placement.
Alison Maher . unresolved

nit: I'd suggest adding more details here on why 2 passes are needed

Line 366, Patchset 1 (Latest): GridLanesRunningPositions running_positions_for_baseline(running_positions);
PlaceAndAlignGridLanesItems(track_collection, grid_lanes_items, start_offset,
running_positions_for_baseline, sizing_constraint,
baseline_accumulator, stacking_axis_gap,
/*is_first_pass=*/true);
Alison Maher . unresolved

Is there any way we can make `must_create_baselines` a member var that is something like `item_has_baseline_alignment_` and that way we don't need to run the first pass in that case?

Line 372, Patchset 1 (Latest): // Second pass: Perform final placement and alignment using computed
Alison Maher . unresolved

nit: "the"

Line 410, Patchset 1 (Latest): const LayoutUnit align_content_offset = AlignContentOffset(
is_for_columns ? intrinsic_block_size_ : intrinsic_inline_size,
is_for_columns ? ChildAvailableSize().block_size
: ChildAvailableSize().inline_size,
baseline_accumulator->FirstBaseline().value_or(LayoutUnit()),
content_alignment);

if (is_for_columns) {
if (ChildAvailableSize().block_size != kIndefiniteSize) {
container_builder_.MoveChildrenInDirection(align_content_offset,
/*is_block_direction=*/true);
}
} else {
if (ChildAvailableSize().inline_size != kIndefiniteSize) {
container_builder_.MoveChildrenInDirection(
align_content_offset, /*is_block_direction=*/false);
}
Alison Maher . unresolved

This method handles alignment as well, so it is unclear PlaceGridLanesItems and PlaceAndAlignGridLanesItems should be different based on names alone. Trying to think of another names

Line 431, Patchset 1 (Latest):void GridLanesLayoutAlgorithm::PlaceAndAlignGridLanesItems(
Alison Maher . unresolved

Would it make sense for this to be an inner method of PlaceGridLanesItems so that we don't need to recalc all the vars below here? Might make reading this kind of confusing though, so not a strong pref

Line 439, Patchset 1 (Latest): bool is_first_pass) {
Alison Maher . unresolved

Instead of a bool, I wonder if it would make sense for this to be an enum:

```
enum PlacementPhase {
kCalculateBaselines,
kFinalPlacement,
}
```

That way it is more clear what the first and seconf pass are for

Line 506, Patchset 1 (Latest): const LogicalBoxFragment baseline_fragment(
grid_lanes_item.BaselineWritingDirection(grid_axis_direction),
To<PhysicalBoxFragment>(result->GetPhysicalFragment()));
Alison Maher . unresolved

Do we only need this if the item has baseline alignment set on itself?

Line 549, Patchset 1 (Latest): // Second pass: Position items and apply baseline alignment.
Alison Maher . unresolved

nit: It might be worth expanding here why this can only be done in the second pass. This also applies other kinds of alignment, so we may want to say "self-alignment" more generically

Line 560, Patchset 1 (Latest): LayoutUnit inline_baseline_offset = ComputeBaselineOffset(
Alison Maher . unresolved

nit: I'd add a space before this one to split things up slightly. We may even want this to go after the inline and block alignment vars below so they are paired with the comment that says "// Adjust item's position in the track based on style."

Line 560, Patchset 1 (Latest): LayoutUnit inline_baseline_offset = ComputeBaselineOffset(
grid_lanes_item, track_collection, baseline_fragment, fragment,
style.GetFontBaseline(), kForColumns,
containing_rect.size.inline_size);
LayoutUnit block_baseline_offset = ComputeBaselineOffset(
grid_lanes_item, track_collection, baseline_fragment, fragment,
style.GetFontBaseline(), kForRows, containing_rect.size.block_size);
Alison Maher . unresolved

Do we only need to do this if the item has baseline alignment set on itself?

Line 618, Patchset 1 (Latest): // Calculate track baseline.
Alison Maher . unresolved

nit: I'd suggest adding more details. Something like "In the first placement pass, we need to calculate the track baseline in order to..."

Line 619, Patchset 1 (Latest): if (is_first_pass &&
grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
Alison Maher . unresolved

If the main point of the first pass is the logic below, could we instead earlier at some point say

```
if (is_first_pass &&
!grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
continue;
```

That way at this point, we could do

```
if (is_first_pass) {
CHECK(grid_lanes_item.IsBaselineAligned(grid_axis_direction));
...
else {
container_builder_.AddResult(*result, containing_rect.offset, margins);
...
}

```

Line 621, Patchset 1 (Latest): const bool has_synthesized_baseline =
!baseline_fragment.FirstBaseline().has_value();
grid_lanes_item.SetAlignmentFallback(grid_axis_direction,
has_synthesized_baseline);
const LayoutUnit extra_margin =
grid_lanes_item.IsLastBaselineSpecified(grid_axis_direction)
? (is_for_columns ? margins.inline_end : margins.block_end)
: (is_for_columns ? margins.inline_start : margins.block_start);
const LayoutUnit item_baseline = GetItemBaseline(
baseline_fragment, style.GetFontBaseline(),
grid_lanes_item.IsLastBaselineSpecified(grid_axis_direction));
const LayoutUnit total_baseline = extra_margin + item_baseline;

// Store baseline in appropriate track.
const auto& [begin_set_index, end_set_index] =
grid_lanes_item.SetIndices(grid_axis_direction);

if (grid_lanes_item.BaselineGroup(grid_axis_direction) ==
BaselineGroup::kMajor) {
track_collection.SetMajorBaseline(begin_set_index, total_baseline);
} else {
track_collection.SetMinorBaseline(end_set_index - 1, total_baseline);
}
Alison Maher . unresolved

Is any of this something we can consolidate with logic in grid, or is this fairly different?

Line 646, Patchset 1 (Latest): if (!is_first_pass) {
Alison Maher . unresolved

nit: I'd suggest adding a comment here why we don't add items in the first pass

Line 1111, Patchset 1 (Latest): if (must_create_baselines) {
Alison Maher . unresolved

nit: this block could use a comment on why when this is true, we reset the baselines

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm_test.cc
Line 61, Patchset 1 (Latest): must_create_baselines)) {
Alison Maher . unresolved

nit: since we only use this var once, we could remove it and update this to `/*must_create_baselines=*/false`

Open in Gerrit

Related details

Attention is currently required from:
  • Kurt Catti-Schmidt
  • Yanling Wang
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I596e51b1a7f6e9cb77ca286b8eb044f6f17971ea
Gerrit-Change-Number: 7408310
Gerrit-PatchSet: 1
Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
Gerrit-Reviewer: Kurt Catti-Schmidt <ksc...@microsoft.com>
Gerrit-Reviewer: Yanling Wang <yanli...@microsoft.com>
Gerrit-CC: Celeste Pan <celes...@microsoft.com>
Gerrit-CC: Javier Fernandez <jfern...@igalia.com>
Gerrit-Attention: Kurt Catti-Schmidt <ksc...@microsoft.com>
Gerrit-Attention: Yanling Wang <yanli...@microsoft.com>
Gerrit-Comment-Date: Wed, 07 Jan 2026 22:27:51 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Kurt Catti-Schmidt (Gerrit)

unread,
Jan 7, 2026, 6:14:37 PM (4 days ago) Jan 7
to Yanling Wang, Alison Maher, Celeste Pan, Chromium LUCI CQ, chromium...@chromium.org, Javier Fernandez, blink-revi...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, zol...@webkit.org
Attention needed from Yanling Wang

Kurt Catti-Schmidt added 5 comments

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
Line 366, Patchset 1 (Latest): GridLanesRunningPositions running_positions_for_baseline(running_positions);
PlaceAndAlignGridLanesItems(track_collection, grid_lanes_items, start_offset,
running_positions_for_baseline, sizing_constraint,
baseline_accumulator, stacking_axis_gap,
/*is_first_pass=*/true);
Alison Maher . unresolved

Is there any way we can make `must_create_baselines` a member var that is something like `item_has_baseline_alignment_` and that way we don't need to run the first pass in that case?

Kurt Catti-Schmidt

Agreed, and most grid-lanes layouts will probably not use baseline alignment, so it can be optimized quite a bit for the general case.

You could make it a member variable or store it on `GridItems` as items are appended.

Line 506, Patchset 1 (Latest): const LogicalBoxFragment baseline_fragment(
grid_lanes_item.BaselineWritingDirection(grid_axis_direction),
To<PhysicalBoxFragment>(result->GetPhysicalFragment()));
Kurt Catti-Schmidt . unresolved

Is this ever going to be different than `physical_fragment`? Can we use that instead?

Line 751, Patchset 1 (Latest): must_create_baselines |=
item_data.IsBaselineSpecified(grid_axis_direction);
Kurt Catti-Schmidt . unresolved

Based on the other comment, this can likely be moved to a member variable or on `GridItems` - that way you won't need the out variable here either.

Line 1112, Patchset 1 (Latest): track_collection.ResetBaselines();
Kurt Catti-Schmidt . unresolved

Is this just to allocate the vectors for baselines? If so, I think this should just happen automatically when `must_create_baselines` is true in the constructor above. You can probably remove a call to `ResetBaselines` in grid if you do this too.

File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-001.html
Line 5, Patchset 1 (Latest): <title>CSS Grid Lanes Test: justify-items:baseline/last baseline</title>
<link rel="author" title="Yanling Wang" href="mailto:yanli...@microsoft.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-3/#masonry-baseline-alignment">
<link rel="match" href="column-grid-lanes-item-baseline-001-ref.html">
Kurt Catti-Schmidt . unresolved

Tests overall are great, but baselines are so complex that there are a few categories not covered.

First, synthesized baselines. For these, you should use the Ahem font and an orthogonal item, see `third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html` and related.

Next, the cyclic dependency cases, which may not apply the same way for masonry, but should be tested regardless, see `third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html` and related.

So a few more test cases and you should be all set re: testing. If they have failures or don't behave as expected, you can add them here and fix in a follow up, as this CL gets most of the functionality.

Open in Gerrit

Related details

Attention is currently required from:
  • Yanling Wang
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I596e51b1a7f6e9cb77ca286b8eb044f6f17971ea
Gerrit-Change-Number: 7408310
Gerrit-PatchSet: 1
Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
Gerrit-Reviewer: Kurt Catti-Schmidt <ksc...@microsoft.com>
Gerrit-Reviewer: Yanling Wang <yanli...@microsoft.com>
Gerrit-CC: Celeste Pan <celes...@microsoft.com>
Gerrit-CC: Javier Fernandez <jfern...@igalia.com>
Gerrit-Attention: Yanling Wang <yanli...@microsoft.com>
Gerrit-Comment-Date: Wed, 07 Jan 2026 23:14:24 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Alison Maher <alm...@microsoft.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Yanling Wang (Gerrit)

unread,
Jan 9, 2026, 7:38:11 PM (2 days ago) Jan 9
to Alison Maher, Kurt Catti-Schmidt, Celeste Pan, Chromium LUCI CQ, chromium...@chromium.org, Javier Fernandez, blink-revi...@chromium.org, blink-revie...@chromium.org, blink-...@chromium.org, zol...@webkit.org
Attention needed from Alison Maher and Kurt Catti-Schmidt

Yanling Wang added 26 comments

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
Line 154, Patchset 1: bool& must_create_baselines) const;
Alison Maher . resolved

Since this is an out pram, I' suggest updating the comment to note what it is and what it gets set to

Yanling Wang

Done

Line 154, Patchset 1: bool& must_create_baselines) const;
Alison Maher . resolved

nit: maybe `needs_baseline` or `needs_baseline_calculation`

Yanling Wang

Thanks for the suggestion! I've updated it to directly use member variable.

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
Line 270, Patchset 1:LayoutUnit TrackBaseline(const GridItemData& grid_lanes_item,
Alison Maher . resolved

This one looks pretty much the same as https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.cc;l=790-807?q=grid_layout_algorithm.cc&ss=chromium

Could we move that one to grid_layout_utils and reuse that here instead? That way if one gets updated, it will work in both.

Yanling Wang

I've moved the core baseline calculation logic to `TrackBaseline()` in grid_layout_utils. I kept the `Baseline()` wrapper in grid_layout_algorithm since it works with GridLayoutData (which bundles row/column collections), while grid-lanes works directly with individual track collections. This way both implementations get the API that fits their data structures while sharing the actual calculation logic.

Line 282, Patchset 1:LayoutUnit GetItemBaseline(const LogicalBoxFragment& baseline_fragment,
Alison Maher . resolved
Yanling Wang

Done

Line 291, Patchset 1:LayoutUnit ComputeBaselineOffset(
Alison Maher . resolved
Yanling Wang

Done

Line 365, Patchset 1: // avoid mutating the state needed for final placement.
Alison Maher . resolved

nit: I'd suggest adding more details here on why 2 passes are needed

Yanling Wang

Done

Line 365, Patchset 1: // avoid mutating the state needed for final placement.
Alison Maher . resolved

Where are things getting mutated? Can we just not mutate it if we are in the first pass?

Yanling Wang

We need to mutate `running_positions` during the first pass in order to place items and determine their baselines. The placement logic requires updating the running positions as items are placed (via FinalizeItemSpanAndGetMaxPosition, UpdateRunningPositionsForSpan, and UpdateAutoPlacementCursor)

Line 366, Patchset 1: GridLanesRunningPositions running_positions_for_baseline(running_positions);

PlaceAndAlignGridLanesItems(track_collection, grid_lanes_items, start_offset,
running_positions_for_baseline, sizing_constraint,
baseline_accumulator, stacking_axis_gap,
/*is_first_pass=*/true);
Alison Maher . resolved

Is there any way we can make `must_create_baselines` a member var that is something like `item_has_baseline_alignment_` and that way we don't need to run the first pass in that case?

Kurt Catti-Schmidt

Agreed, and most grid-lanes layouts will probably not use baseline alignment, so it can be optimized quite a bit for the general case.

You could make it a member variable or store it on `GridItems` as items are appended.

Yanling Wang

Thanks for the suggestions! I've made it a member variable and optimized this for the general case.

Line 372, Patchset 1: // Second pass: Perform final placement and alignment using computed
Alison Maher . resolved

nit: "the"

Yanling Wang

Done

Line 410, Patchset 1: const LayoutUnit align_content_offset = AlignContentOffset(

is_for_columns ? intrinsic_block_size_ : intrinsic_inline_size,
is_for_columns ? ChildAvailableSize().block_size
: ChildAvailableSize().inline_size,
baseline_accumulator->FirstBaseline().value_or(LayoutUnit()),
content_alignment);

if (is_for_columns) {
if (ChildAvailableSize().block_size != kIndefiniteSize) {
container_builder_.MoveChildrenInDirection(align_content_offset,
/*is_block_direction=*/true);
}
} else {
if (ChildAvailableSize().inline_size != kIndefiniteSize) {
container_builder_.MoveChildrenInDirection(
align_content_offset, /*is_block_direction=*/false);
}
Alison Maher . unresolved

This method handles alignment as well, so it is unclear PlaceGridLanesItems and PlaceAndAlignGridLanesItems should be different based on names alone. Trying to think of another names

Yanling Wang

Thanks for the feedback! I've renamed the `PlaceAndAlignGridLanesItems` to `LayoutEachGridLanesItem` since it iterates through and processes each individual item - performs layout, placement, and item alignment. Please let me know if you feel there's a more appropriate name for it.

Line 431, Patchset 1:void GridLanesLayoutAlgorithm::PlaceAndAlignGridLanesItems(
Alison Maher . resolved

Would it make sense for this to be an inner method of PlaceGridLanesItems so that we don't need to recalc all the vars below here? Might make reading this kind of confusing though, so not a strong pref

Yanling Wang

Thanks for the suggestion! I feel like it's better to keep it as is for readability, since the method is already quite long.

Line 439, Patchset 1: bool is_first_pass) {
Alison Maher . resolved

Instead of a bool, I wonder if it would make sense for this to be an enum:

```
enum PlacementPhase {
kCalculateBaselines,
kFinalPlacement,
}
```

That way it is more clear what the first and seconf pass are for

Yanling Wang

Done

Line 506, Patchset 1: const LogicalBoxFragment baseline_fragment(

grid_lanes_item.BaselineWritingDirection(grid_axis_direction),
To<PhysicalBoxFragment>(result->GetPhysicalFragment()));
Kurt Catti-Schmidt . resolved

Is this ever going to be different than `physical_fragment`? Can we use that instead?

Yanling Wang

The `baseline_fragment` uses BaselineWritingDirection(grid_axis_direction) rather than the container's writing direction. This ensures baselines are calculated relative to the correct axis.

Line 506, Patchset 1: const LogicalBoxFragment baseline_fragment(

grid_lanes_item.BaselineWritingDirection(grid_axis_direction),
To<PhysicalBoxFragment>(result->GetPhysicalFragment()));
Alison Maher . resolved

Do we only need this if the item has baseline alignment set on itself?

Yanling Wang

Thanks for the feedback. I've optimized the code to only create baseline_fragment when it's actually needed.

Line 549, Patchset 1: // Second pass: Position items and apply baseline alignment.
Alison Maher . resolved

nit: It might be worth expanding here why this can only be done in the second pass. This also applies other kinds of alignment, so we may want to say "self-alignment" more generically

Yanling Wang

Done

Line 560, Patchset 1: LayoutUnit inline_baseline_offset = ComputeBaselineOffset(
Alison Maher . resolved

nit: I'd add a space before this one to split things up slightly. We may even want this to go after the inline and block alignment vars below so they are paired with the comment that says "// Adjust item's position in the track based on style."

Yanling Wang

Done

Line 560, Patchset 1: LayoutUnit inline_baseline_offset = ComputeBaselineOffset(

grid_lanes_item, track_collection, baseline_fragment, fragment,
style.GetFontBaseline(), kForColumns,
containing_rect.size.inline_size);
LayoutUnit block_baseline_offset = ComputeBaselineOffset(
grid_lanes_item, track_collection, baseline_fragment, fragment,
style.GetFontBaseline(), kForRows, containing_rect.size.block_size);
Alison Maher . unresolved

Do we only need to do this if the item has baseline alignment set on itself?

Yanling Wang

You're right that the baseline_offset is only meaningful to those items have baseline alignment set on itself. The `ComputeBaselineOffset` already has an early return for non-baseline items, and LogicalBoxFragment creation is a lightweight wrapper. I don't feel like we need to add an additional check here.

Line 618, Patchset 1: // Calculate track baseline.
Alison Maher . resolved

nit: I'd suggest adding more details. Something like "In the first placement pass, we need to calculate the track baseline in order to..."

Yanling Wang

Done

Line 619, Patchset 1: if (is_first_pass &&
grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
Alison Maher . resolved

If the main point of the first pass is the logic below, could we instead earlier at some point say

```
if (is_first_pass &&
!grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
continue;
```

That way at this point, we could do

```
if (is_first_pass) {
CHECK(grid_lanes_item.IsBaselineAligned(grid_axis_direction));
...
else {
container_builder_.AddResult(*result, containing_rect.offset, margins);
...
}

```

Yanling Wang

Done

Line 621, Patchset 1: const bool has_synthesized_baseline =

!baseline_fragment.FirstBaseline().has_value();
grid_lanes_item.SetAlignmentFallback(grid_axis_direction,
has_synthesized_baseline);
const LayoutUnit extra_margin =
grid_lanes_item.IsLastBaselineSpecified(grid_axis_direction)
? (is_for_columns ? margins.inline_end : margins.block_end)
: (is_for_columns ? margins.inline_start : margins.block_start);
const LayoutUnit item_baseline = GetItemBaseline(
baseline_fragment, style.GetFontBaseline(),
grid_lanes_item.IsLastBaselineSpecified(grid_axis_direction));
const LayoutUnit total_baseline = extra_margin + item_baseline;

// Store baseline in appropriate track.
const auto& [begin_set_index, end_set_index] =
grid_lanes_item.SetIndices(grid_axis_direction);

if (grid_lanes_item.BaselineGroup(grid_axis_direction) ==
BaselineGroup::kMajor) {
track_collection.SetMajorBaseline(begin_set_index, total_baseline);
} else {
track_collection.SetMinorBaseline(end_set_index - 1, total_baseline);
}
Alison Maher . resolved

Is any of this something we can consolidate with logic in grid, or is this fairly different?

Yanling Wang

Good suggestion! I've consolidated the shared baseline calculation logic into a helper function `StoreItemBaseline()`

Line 646, Patchset 1: if (!is_first_pass) {
Alison Maher . resolved

nit: I'd suggest adding a comment here why we don't add items in the first pass

Yanling Wang

Done

Line 751, Patchset 1: must_create_baselines |=
item_data.IsBaselineSpecified(grid_axis_direction);
Kurt Catti-Schmidt . resolved

Based on the other comment, this can likely be moved to a member variable or on `GridItems` - that way you won't need the out variable here either.

Yanling Wang

Done

Line 1111, Patchset 1: if (must_create_baselines) {
Alison Maher . resolved

nit: this block could use a comment on why when this is true, we reset the baselines

Yanling Wang

Done

Line 1112, Patchset 1: track_collection.ResetBaselines();
Kurt Catti-Schmidt . resolved

Is this just to allocate the vectors for baselines? If so, I think this should just happen automatically when `must_create_baselines` is true in the constructor above. You can probably remove a call to `ResetBaselines` in grid if you do this too.

Yanling Wang

The constructor creates the baselines_ container (`baselines_.emplace()`) when `must_create_baselines` is true, but can't allocate the major/minor baseline vectors yet since the set count is unknown until `BuildSets()` completes. `ResetBaselines()` allocates those vectors once we know the count. I've added a comment to clarify this.

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm_test.cc
Line 61, Patchset 1: must_create_baselines)) {
Alison Maher . resolved

nit: since we only use this var once, we could remove it and update this to `/*must_create_baselines=*/false`

Yanling Wang

I've removed this since we decided to use member variable instead. Thanks!

File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-001.html
Line 5, Patchset 1: <title>CSS Grid Lanes Test: justify-items:baseline/last baseline</title>

<link rel="author" title="Yanling Wang" href="mailto:yanli...@microsoft.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-3/#masonry-baseline-alignment">
<link rel="match" href="column-grid-lanes-item-baseline-001-ref.html">
Kurt Catti-Schmidt . resolved

Tests overall are great, but baselines are so complex that there are a few categories not covered.

First, synthesized baselines. For these, you should use the Ahem font and an orthogonal item, see `third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html` and related.

Next, the cyclic dependency cases, which may not apply the same way for masonry, but should be tested regardless, see `third_party/blink/web_tests/external/wpt/css/css-grid/alignment/grid-self-baseline-not-applied-if-sizing-cyclic-dependency-001.html` and related.

So a few more test cases and you should be all set re: testing. If they have failures or don't behave as expected, you can add them here and fix in a follow up, as this CL gets most of the functionality.

Yanling Wang

Added more tests for it, thanks for the feedback!

Open in Gerrit

Related details

Attention is currently required from:
  • Alison Maher
  • Kurt Catti-Schmidt
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I596e51b1a7f6e9cb77ca286b8eb044f6f17971ea
Gerrit-Change-Number: 7408310
Gerrit-PatchSet: 2
Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
Gerrit-Reviewer: Kurt Catti-Schmidt <ksc...@microsoft.com>
Gerrit-Reviewer: Yanling Wang <yanli...@microsoft.com>
Gerrit-CC: Celeste Pan <celes...@microsoft.com>
Gerrit-CC: Javier Fernandez <jfern...@igalia.com>
Gerrit-Attention: Alison Maher <alm...@microsoft.com>
Gerrit-Attention: Kurt Catti-Schmidt <ksc...@microsoft.com>
Gerrit-Comment-Date: Sat, 10 Jan 2026 00:38:02 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Alison Maher <alm...@microsoft.com>
Comment-In-Reply-To: Kurt Catti-Schmidt <ksc...@microsoft.com>
satisfied_requirement
unsatisfied_requirement
open
diffy
Reply all
Reply to author
Forward
0 new messages