[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:04 PM (10 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:35 PM (10 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:12 PM (8 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

Alison Maher (Gerrit)

unread,
Jan 12, 2026, 1:55:45 PM (5 days ago) Jan 12
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 28 comments

File third_party/blink/renderer/core/layout/grid/grid_layout_utils.h
Line 146, Patchset 2 (Latest): GridSizingTrackCollection& track_collection,
GridItemData& item,
Alison Maher . unresolved

Are these both out params? If so, it'd be good to add this to the comment. Also if they are, they should be moved to the bottom of the variable list per the C++ style guide.

If not, then can these be const?

File third_party/blink/renderer/core/layout/grid/grid_layout_utils.cc
Line 21, Patchset 2 (Latest):LayoutUnit TrackBaseline(const GridItemData& grid_item,
Alison Maher . unresolved

nit: GetTrackBaseline to match the method naming below

Line 46, Patchset 2 (Latest):void StoreItemBaseline(const LogicalBoxFragment& baseline_fragment,
Alison Maher . unresolved

Would Set make sense here? If not, ok with Store

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
Line 208, Patchset 2 (Latest): mutable bool has_baseline_aligned_items_ = false;
Alison Maher . unresolved

Is this needed? Should be mutable without this I think

Line 207, Patchset 2 (Latest): // indicating that a two-pass placement is needed to compute track baselines.
Alison Maher . unresolved

"and final item placement"

Line 206, Patchset 2 (Latest): // Set to true if any item in the grid-lanes layout has baseline alignment,
Alison Maher . unresolved

"When true, there is at least one item that is baseline aligned, indicating..."

Line 81, Patchset 2 (Latest): LayoutUnit stacking_axis_gap,
PlacementPhase placement_phase);
Alison Maher . unresolved

These and `sizing_constraint` look to be input params. According to the style guide, output params should always be placed last, so these should move up above `running_positions`

Line 74, Patchset 2 (Latest): void LayoutEachGridLanesItem(
Alison Maher . unresolved

Maybe something like `RunGridLanesPlacementPhase()`

Line 69, Patchset 2 (Latest): // Iterates through and lays out each grid-lanes item in two passes to handle
Alison Maher . unresolved

This comment kind of implies that there are always two passes, and that this method running both. Instead, the caller handles running the passes, and this method does something different depending on the pass.

Given this, I wonder if we should update this to just note what happens if called with each type of placement phase.

i.e.

"This method iterates through and lays out each item in `grid_lanes_items`. If `placement_phase` is kCalculateBaselines, that means.... If `placement_phase` is kFinalPlacement, that means..."

I'd also suggest mentioning the out params in the comment (running_positions, baseline_accumulator)

Line 69, Patchset 2 (Latest): // Iterates through and lays out each grid-lanes item in two passes to handle
Alison Maher . unresolved

nit: "item in `grid_lanes_items`"

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
Line 314, Patchset 2 (Latest): // Baseline alignment requires two passes if any items use baseline alignment.
Alison Maher . unresolved

"If an item is baseline aligned, placement is required in two passes because..."

Line 315, Patchset 2 (Latest): // Most grid-lanes layouts don't use baseline alignment, so we can optimize
// by skipping the first pass when it's not needed.
Alison Maher . unresolved

This comment can be removed since it is implied

Line 318, Patchset 2 (Latest): // First pass: Compute track baselines by placing items to determine their
Alison Maher . unresolved

Instead of saying "First pass:" maybe something like "In the initial placemet pass, compute..."

Line 319, Patchset 2 (Latest): // positions and baselines. This pass mutates running_positions through
Alison Maher . unresolved

nit: missing ``

Line 321, Patchset 2 (Latest): // UpdateAutoPlacementCursor() calls. We use a copy to preserve the original
Alison Maher . unresolved

"of `running_positoins`"

Line 321, Patchset 2 (Latest): // UpdateAutoPlacementCursor() calls. We use a copy to preserve the original
Alison Maher . unresolved

"their"

Line 319, Patchset 2 (Latest): // positions and baselines. This pass mutates running_positions through
// FinalizeItemSpanAndGetMaxPosition(), UpdateRunningPositionsForSpan(), and
// UpdateAutoPlacementCursor() calls. We use a copy to preserve the original
Alison Maher . unresolved

Instead of noting where it is mutated, I think just noting what we need running positions for in the first pass would be sufficient

Line 330, Patchset 2 (Latest): // Final placement pass (second pass if baseline alignment needed, otherwise
// the only pass).
Alison Maher . unresolved

nit: "Run a final placement pass of all items and add their layout results to the container. This is the second placement pass if there are any items requiring baseline alignment, and the only placement pass otherwise."

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 . resolved

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.

Alison Maher

Acknowledged

Line 504, Patchset 2 (Latest): // Final placement pass: Position items and apply self-alignment. This must
Alison Maher . unresolved

nit: "In the final placement pass, position items..."

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 . resolved

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.

Alison Maher

Acknowledged

Line 583, Patchset 2 (Latest): // after running position updates.
Alison Maher . unresolved

nit: could you add more details why. i.e. "This check must happen after the running position updates because..."

Line 583, Patchset 2 (Latest): // after running position updates.
Alison Maher . unresolved

nit: "the"

Line 584, Patchset 2 (Latest): if (placement_phase == PlacementPhase::kCalculateBaselines &&
!grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
continue;
}

if (placement_phase == PlacementPhase::kCalculateBaselines) {
Alison Maher . unresolved

nit: these can be combined

```
if (placement_phase == PlacementPhase::kCalculateBaselines
// <move your comment from above here>
if (!grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
continue;
}
...
}
Line 590, Patchset 2 (Latest): CHECK(grid_lanes_item.IsBaselineAligned(grid_axis_direction));
Alison Maher . unresolved

If we adjust as mentioned above, this would be implied and can be removed

Line 608, Patchset 2 (Latest): // PlacementPhase::kFinalPlacement.
//
Alison Maher . unresolved

nit: This part of the comment can be removed

Line 610, Patchset 2 (Latest): // Items are only added to the container in the final placement pass.
// During the baseline calculation pass, we only compute and store track
// baselines without adding items, since baseline information is needed
// before items can be properly aligned and placed.
Alison Maher . unresolved

This is a great comment! I think some of these details around when item layout results are added to the container can be added to the comments at the call sites for this method, and perhaps in the comment for this method in the header, as well.

Line 1078, Patchset 2 (Latest): // Allocate baseline storage. The constructor creates the `baselines_`
Alison Maher . unresolved

It's not clear what ctr this is referring to just by reading this. May be able to just simplify to "Allocate the major/minor baseline vectors now that we now the total size."

The name "Reset" also makes me think it could be used not just on constructing but resetting at some later point. Is that true, or is it just on set up?

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: 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: Kurt Catti-Schmidt <ksc...@microsoft.com>
Gerrit-Attention: Yanling Wang <yanli...@microsoft.com>
Gerrit-Comment-Date: Mon, 12 Jan 2026 18:55:35 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Alison Maher <alm...@microsoft.com>
Comment-In-Reply-To: Yanling Wang <yanli...@microsoft.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Yanling Wang (Gerrit)

unread,
Jan 14, 2026, 12:06:16 PM (3 days ago) Jan 14
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/grid_layout_utils.h
Line 146, Patchset 2: GridSizingTrackCollection& track_collection,
GridItemData& item,
Alison Maher . resolved

Are these both out params? If so, it'd be good to add this to the comment. Also if they are, they should be moved to the bottom of the variable list per the C++ style guide.

If not, then can these be const?

Yanling Wang

Yes, they're both out params. Thanks for pointing out, I've updated it.

File third_party/blink/renderer/core/layout/grid/grid_layout_utils.cc
Line 21, Patchset 2:LayoutUnit TrackBaseline(const GridItemData& grid_item,
Alison Maher . resolved

nit: GetTrackBaseline to match the method naming below

Yanling Wang

Done

Line 46, Patchset 2:void StoreItemBaseline(const LogicalBoxFragment& baseline_fragment,
Alison Maher . resolved

Would Set make sense here? If not, ok with Store

Yanling Wang

I feel like "store" better reflects that we're storing baseline contributions from individual items into the track collection, rather than just setting a value.

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
Line 208, Patchset 2: mutable bool has_baseline_aligned_items_ = false;
Alison Maher . resolved

Is this needed? Should be mutable without this I think

Yanling Wang

The mutable is needed here because we modified it in the const method BuildVirtualGridLanesItems(), so without mutable the code won't compile.

Line 207, Patchset 2: // indicating that a two-pass placement is needed to compute track baselines.
Alison Maher . resolved

"and final item placement"

Yanling Wang

Done

Line 206, Patchset 2: // Set to true if any item in the grid-lanes layout has baseline alignment,
Alison Maher . resolved

"When true, there is at least one item that is baseline aligned, indicating..."

Yanling Wang

Done

Line 81, Patchset 2: LayoutUnit stacking_axis_gap,
PlacementPhase placement_phase);
Alison Maher . resolved

These and `sizing_constraint` look to be input params. According to the style guide, output params should always be placed last, so these should move up above `running_positions`

Yanling Wang

thanks for pointing out, I've updated it.

Line 74, Patchset 2: void LayoutEachGridLanesItem(
Alison Maher . resolved

Maybe something like `RunGridLanesPlacementPhase()`

Yanling Wang

This makes more sense, I've updated it, thanks!

Line 69, Patchset 2: // Iterates through and lays out each grid-lanes item in two passes to handle
Alison Maher . resolved

This comment kind of implies that there are always two passes, and that this method running both. Instead, the caller handles running the passes, and this method does something different depending on the pass.

Given this, I wonder if we should update this to just note what happens if called with each type of placement phase.

i.e.

"This method iterates through and lays out each item in `grid_lanes_items`. If `placement_phase` is kCalculateBaselines, that means.... If `placement_phase` is kFinalPlacement, that means..."

I'd also suggest mentioning the out params in the comment (running_positions, baseline_accumulator)

Yanling Wang

Done

Line 69, Patchset 2: // Iterates through and lays out each grid-lanes item in two passes to handle
Alison Maher . resolved

nit: "item in `grid_lanes_items`"

Yanling Wang

Done

File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
Line 314, Patchset 2: // Baseline alignment requires two passes if any items use baseline alignment.
Alison Maher . resolved

"If an item is baseline aligned, placement is required in two passes because..."

Yanling Wang

Done

Line 315, Patchset 2: // Most grid-lanes layouts don't use baseline alignment, so we can optimize

// by skipping the first pass when it's not needed.
Alison Maher . resolved

This comment can be removed since it is implied

Yanling Wang

Done

Line 318, Patchset 2: // First pass: Compute track baselines by placing items to determine their
Alison Maher . resolved

Instead of saying "First pass:" maybe something like "In the initial placemet pass, compute..."

Yanling Wang

Done

Line 319, Patchset 2: // positions and baselines. This pass mutates running_positions through
Alison Maher . resolved

nit: missing ``

Yanling Wang

Done

Line 321, Patchset 2: // UpdateAutoPlacementCursor() calls. We use a copy to preserve the original
Alison Maher . resolved

"their"

Yanling Wang

Done

Line 321, Patchset 2: // UpdateAutoPlacementCursor() calls. We use a copy to preserve the original
Alison Maher . resolved

"of `running_positoins`"

Yanling Wang

Done

Line 319, Patchset 2: // positions and baselines. This pass mutates running_positions through

// FinalizeItemSpanAndGetMaxPosition(), UpdateRunningPositionsForSpan(), and
// UpdateAutoPlacementCursor() calls. We use a copy to preserve the original
Alison Maher . resolved

Instead of noting where it is mutated, I think just noting what we need running positions for in the first pass would be sufficient

Yanling Wang

Done

Line 330, Patchset 2: // Final placement pass (second pass if baseline alignment needed, otherwise
// the only pass).
Alison Maher . resolved

nit: "Run a final placement pass of all items and add their layout results to the container. This is the second placement pass if there are any items requiring baseline alignment, and the only placement pass otherwise."

Yanling Wang

Done

Line 504, Patchset 2: // Final placement pass: Position items and apply self-alignment. This must
Alison Maher . resolved

nit: "In the final placement pass, position items..."

Yanling Wang

Done

Line 583, Patchset 2: // after running position updates.
Alison Maher . resolved

nit: "the"

Yanling Wang

Done

Line 583, Patchset 2: // after running position updates.
Alison Maher . resolved

nit: could you add more details why. i.e. "This check must happen after the running position updates because..."

Yanling Wang

Done

Line 584, Patchset 2: if (placement_phase == PlacementPhase::kCalculateBaselines &&

!grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
continue;
}

if (placement_phase == PlacementPhase::kCalculateBaselines) {
Alison Maher . resolved

nit: these can be combined

```
if (placement_phase == PlacementPhase::kCalculateBaselines
// <move your comment from above here>
if (!grid_lanes_item.IsBaselineAligned(grid_axis_direction)) {
continue;
}
...
}
Yanling Wang

Done

Line 590, Patchset 2: CHECK(grid_lanes_item.IsBaselineAligned(grid_axis_direction));
Alison Maher . resolved

If we adjust as mentioned above, this would be implied and can be removed

Yanling Wang

Done

Line 608, Patchset 2: // PlacementPhase::kFinalPlacement.
//
Alison Maher . resolved

nit: This part of the comment can be removed

Yanling Wang

Done

Line 610, Patchset 2: // Items are only added to the container in the final placement pass.

// During the baseline calculation pass, we only compute and store track
// baselines without adding items, since baseline information is needed
// before items can be properly aligned and placed.
Alison Maher . resolved

This is a great comment! I think some of these details around when item layout results are added to the container can be added to the comments at the call sites for this method, and perhaps in the comment for this method in the header, as well.

Yanling Wang

Done

Line 1078, Patchset 2: // Allocate baseline storage. The constructor creates the `baselines_`
Alison Maher . resolved

It's not clear what ctr this is referring to just by reading this. May be able to just simplify to "Allocate the major/minor baseline vectors now that we now the total size."

The name "Reset" also makes me think it could be used not just on constructing but resetting at some later point. Is that true, or is it just on set up?

Yanling Wang

Yes, that's true for "reset". Because the grid computes the item baseline during track sizing, it was called multiple times to clears and reallocates the baseline vectors when baselines need to be recomputed in the track sizing algorithm, not just on initial construction.

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 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: 4
    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: Wed, 14 Jan 2026 17:06:03 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Alison Maher (Gerrit)

    unread,
    Jan 14, 2026, 1:48:47 PM (3 days ago) Jan 14
    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 6 comments

    File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
    Line 208, Patchset 2: mutable bool has_baseline_aligned_items_ = false;
    Alison Maher . unresolved

    Is this needed? Should be mutable without this I think

    Yanling Wang

    The mutable is needed here because we modified it in the const method BuildVirtualGridLanesItems(), so without mutable the code won't compile.

    Alison Maher

    Is it possible just to make that method non-const?

    File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
    Line 572, Patchset 4 (Latest): 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

    So here we pass in kForRows in one and kForColumns in the other. Shouldn't only one apply in masonry? And as such, would only one direction of alignment apply depending on the direction of the container?

    File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
    Line 16, Patchset 2: grid-auto-flow: dense;
    Alison Maher . unresolved

    We were asked to keep both syntaxes for dense packing, so would you be able to add this back, alongside the grid-lanes-pack property? Same with the similar row test

    Line 121, Patchset 4 (Latest):<div class="grid-lanes lb">
    Alison Maher . unresolved

    Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

    File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-cyclic-dependency-001-ref.html
    Line 2, Patchset 4 (Latest):<html>
    Alison Maher . unresolved

    We might want to split this test out since the wpt runner has limited size and this looks like it might cause overflow

    File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-cyclic-dependency-002.html
    Line 76, Patchset 4 (Latest): <pre>flex max-function columns - items with relative width<br>baseline is not applied initially, but orthogonal items in an auto-sized row force repeating the track sizing and height is not indefinite in that phase.</pre>
    Alison Maher . unresolved

    There should be no rows here since this is a column test

    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: 4
      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, 14 Jan 2026 18:48:34 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Alison Maher <alm...@microsoft.com>
      Comment-In-Reply-To: Yanling Wang <yanli...@microsoft.com>
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Yanling Wang (Gerrit)

      unread,
      Jan 15, 2026, 12:30:19 PM (2 days ago) Jan 15
      to Ian Kilpatrick, 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, Ian Kilpatrick and Kurt Catti-Schmidt

      Yanling Wang added 6 comments

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
      Line 208, Patchset 2: mutable bool has_baseline_aligned_items_ = false;
      Alison Maher . resolved

      Is this needed? Should be mutable without this I think

      Yanling Wang

      The mutable is needed here because we modified it in the const method BuildVirtualGridLanesItems(), so without mutable the code won't compile.

      Alison Maher

      Is it possible just to make that method non-const?

      Yanling Wang

      updated the method to be non-const.

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
      Line 572, Patchset 4: 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

      So here we pass in kForRows in one and kForColumns in the other. Shouldn't only one apply in masonry? And as such, would only one direction of alignment apply depending on the direction of the container?

      Yanling Wang

      You're correct that only one direction applies in masonry. However, `ComputeBaselineOffset` already handles this internally - it has an early check that returns `LayoutUnit()` (zero offset) if the item is not baseline-aligned in the specified direction:

      For instance, when `is_for_columns` is `true`:

      `inline_alignment` uses the actual alignment, so `inline_baseline_offset` may be non-zero
      `block_alignment` is forced to `kStart`, so `ComputeBaselineOffset` returns 0 for `block_baseline_offset`
      And vice versa when `is_for_columns` is `false`.

      While we could add a conditional to avoid the call entirely (e.g., inline_baseline_offset = is_for_columns ? ComputeBaselineOffset(...) : LayoutUnit()), it would add extra logic for it since the function already optimizes this internally.

      File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
      Line 16, Patchset 2: grid-auto-flow: dense;
      Alison Maher . resolved

      We were asked to keep both syntaxes for dense packing, so would you be able to add this back, alongside the grid-lanes-pack property? Same with the similar row test

      Yanling Wang

      Done

      Line 121, Patchset 4:<div class="grid-lanes lb">
      Alison Maher . unresolved

      Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

      Yanling Wang

      I think this is the expected behavior based on grid baseline alignment calculation. When using "justify-items: last baseline", items are aligned by their last baseline, which can cause them to extend beyond their grid area boundaries and overlap with other items.
      For last baseline alignment (minor baseline group), the offset calculation is:
      `return available_size - baseline_delta - item_size;`

      The reference file demonstrates what grid produces in this scenario, and the test verifies that grid-lanes matches this behavior.

      File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-cyclic-dependency-001-ref.html
      Line 2, Patchset 4:<html>
      Alison Maher . resolved

      We might want to split this test out since the wpt runner has limited size and this looks like it might cause overflow

      Yanling Wang

      Done

      File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-cyclic-dependency-002.html
      Line 76, Patchset 4: <pre>flex max-function columns - items with relative width<br>baseline is not applied initially, but orthogonal items in an auto-sized row force repeating the track sizing and height is not indefinite in that phase.</pre>
      Alison Maher . resolved

      There should be no rows here since this is a column test

      Yanling Wang

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Alison Maher
      • Ian Kilpatrick
      • 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: 5
      Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
      Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
      Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
      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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
      Gerrit-Comment-Date: Thu, 15 Jan 2026 17:30:09 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Alison Maher (Gerrit)

      unread,
      Jan 15, 2026, 3:06:35 PM (2 days ago) Jan 15
      to Yanling Wang, Ian Kilpatrick, 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 Ian Kilpatrick, Kurt Catti-Schmidt and Yanling Wang

      Alison Maher added 2 comments

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
      Line 572, Patchset 4: 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

      So here we pass in kForRows in one and kForColumns in the other. Shouldn't only one apply in masonry? And as such, would only one direction of alignment apply depending on the direction of the container?

      Yanling Wang

      You're correct that only one direction applies in masonry. However, `ComputeBaselineOffset` already handles this internally - it has an early check that returns `LayoutUnit()` (zero offset) if the item is not baseline-aligned in the specified direction:

      For instance, when `is_for_columns` is `true`:

      `inline_alignment` uses the actual alignment, so `inline_baseline_offset` may be non-zero
      `block_alignment` is forced to `kStart`, so `ComputeBaselineOffset` returns 0 for `block_baseline_offset`
      And vice versa when `is_for_columns` is `false`.

      While we could add a conditional to avoid the call entirely (e.g., inline_baseline_offset = is_for_columns ? ComputeBaselineOffset(...) : LayoutUnit()), it would add extra logic for it since the function already optimizes this internally.

      Alison Maher

      What happens though if the item does have justify-self: baseline set, but the container doesn't support justify-self because it is a row container. Will ComputeBaselineOffset return LayoutUnit() in that case? It seems to just check if the item alignment matches the track direction, and we will pass in both track directions.

      If it still calculates a baseline in that case, we may want to scope to only one here

      File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
      Line 121, Patchset 4:<div class="grid-lanes lb">
      Alison Maher . unresolved

      Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

      Yanling Wang

      I think this is the expected behavior based on grid baseline alignment calculation. When using "justify-items: last baseline", items are aligned by their last baseline, which can cause them to extend beyond their grid area boundaries and overlap with other items.
      For last baseline alignment (minor baseline group), the offset calculation is:
      `return available_size - baseline_delta - item_size;`

      The reference file demonstrates what grid produces in this scenario, and the test verifies that grid-lanes matches this behavior.

      Alison Maher

      If it matches grid, that seems reasonable, so no need to block on this comment. But just so I understand, it sounds like internally, the major axis is the first baseline, and the minor axis is the last baseline.

      So since these are using last baseline, we go down the minor baseline path. In this test, which items are aligned up with which? i.e. what are the alignment groups (I wouldn't have thought it's items in the same column). And why do some seem to align towards the left side of the container, and some on the right? Is it because of spanning items? Happy to chat offline to better understand this one

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Kilpatrick
      • 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: 5
      Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
      Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
      Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
      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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
      Gerrit-Comment-Date: Thu, 15 Jan 2026 20:06:19 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Kurt Catti-Schmidt (Gerrit)

      unread,
      Jan 16, 2026, 12:18:18 PM (yesterday) Jan 16
      to Yanling Wang, Ian Kilpatrick, 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 Ian Kilpatrick and Yanling Wang

      Kurt Catti-Schmidt added 2 comments

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
      Line 208, Patchset 2: mutable bool has_baseline_aligned_items_ = false;
      Alison Maher . unresolved

      Is this needed? Should be mutable without this I think

      Yanling Wang

      The mutable is needed here because we modified it in the const method BuildVirtualGridLanesItems(), so without mutable the code won't compile.

      Alison Maher

      Is it possible just to make that method non-const?

      Kurt Catti-Schmidt

      If we do want to make these methods const again, adding it to `GridItemData` instead will be easier, and it'll be optimal if you check when each item is appended.

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
      Line 572, Patchset 4: 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

      So here we pass in kForRows in one and kForColumns in the other. Shouldn't only one apply in masonry? And as such, would only one direction of alignment apply depending on the direction of the container?

      Kurt Catti-Schmidt

      This should effectively be what happens, but it's not super clear looking at the code (`ComputeBaselineOffset` will return 0 if there's no alignment in that dimension). This could definitely use a comment though, because it looks like it's doing extra work.

      @yanli...@microsoft.com, can you add a test where both align and justify are set with grid-lanes and make sure it's not applying both types of alignment?

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Ian Kilpatrick
      • 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: 7
      Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
      Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
      Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
      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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
      Gerrit-Comment-Date: Fri, 16 Jan 2026 17:18:07 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Alison Maher (Gerrit)

      unread,
      Jan 16, 2026, 12:21:23 PM (yesterday) Jan 16
      to Yanling Wang, Ian Kilpatrick, 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 Ian Kilpatrick and Yanling Wang

      Alison Maher added 1 comment

      File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
      Line 121, Patchset 4:<div class="grid-lanes lb">
      Alison Maher . resolved

      Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

      Yanling Wang

      I think this is the expected behavior based on grid baseline alignment calculation. When using "justify-items: last baseline", items are aligned by their last baseline, which can cause them to extend beyond their grid area boundaries and overlap with other items.
      For last baseline alignment (minor baseline group), the offset calculation is:
      `return available_size - baseline_delta - item_size;`

      The reference file demonstrates what grid produces in this scenario, and the test verifies that grid-lanes matches this behavior.

      Alison Maher

      If it matches grid, that seems reasonable, so no need to block on this comment. But just so I understand, it sounds like internally, the major axis is the first baseline, and the minor axis is the last baseline.

      So since these are using last baseline, we go down the minor baseline path. In this test, which items are aligned up with which? i.e. what are the alignment groups (I wouldn't have thought it's items in the same column). And why do some seem to align towards the left side of the container, and some on the right? Is it because of spanning items? Happy to chat offline to better understand this one

      Alison Maher

      Confirmed offline what is going on here, so closing this out

      Gerrit-Comment-Date: Fri, 16 Jan 2026 17:21:14 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Yanling Wang (Gerrit)

      unread,
      Jan 16, 2026, 4:57:42 PM (20 hours ago) Jan 16
      to Ian Kilpatrick, 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, Ian Kilpatrick and Kurt Catti-Schmidt

      Yanling Wang added 3 comments

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.h
      Line 208, Patchset 2: mutable bool has_baseline_aligned_items_ = false;
      Alison Maher . resolved

      Is this needed? Should be mutable without this I think

      Yanling Wang

      The mutable is needed here because we modified it in the const method BuildVirtualGridLanesItems(), so without mutable the code won't compile.

      Alison Maher

      Is it possible just to make that method non-const?

      Kurt Catti-Schmidt

      If we do want to make these methods const again, adding it to `GridItemData` instead will be easier, and it'll be optimal if you check when each item is appended.

      Yanling Wang

      I considered adding it to `GridItemData`, but that would require iterating all items every time we need to check if the container has baseline-aligned items. The current approach gives us O(1) lookup since has_baseline_aligned_items_ is a container-level flag. We discover baseline alignment during virtual item creation in BuildVirtualGridLanesItems(), which naturally modifies the algorithm's state, so making these methods non-const is semantically reasonable and avoids the `mutable`

      File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
      Line 572, Patchset 4: 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 . resolved

      So here we pass in kForRows in one and kForColumns in the other. Shouldn't only one apply in masonry? And as such, would only one direction of alignment apply depending on the direction of the container?

      Yanling Wang

      You're correct that only one direction applies in masonry. However, `ComputeBaselineOffset` already handles this internally - it has an early check that returns `LayoutUnit()` (zero offset) if the item is not baseline-aligned in the specified direction:

      For instance, when `is_for_columns` is `true`:

      `inline_alignment` uses the actual alignment, so `inline_baseline_offset` may be non-zero
      `block_alignment` is forced to `kStart`, so `ComputeBaselineOffset` returns 0 for `block_baseline_offset`
      And vice versa when `is_for_columns` is `false`.

      While we could add a conditional to avoid the call entirely (e.g., inline_baseline_offset = is_for_columns ? ComputeBaselineOffset(...) : LayoutUnit()), it would add extra logic for it since the function already optimizes this internally.

      Alison Maher

      What happens though if the item does have justify-self: baseline set, but the container doesn't support justify-self because it is a row container. Will ComputeBaselineOffset return LayoutUnit() in that case? It seems to just check if the item alignment matches the track direction, and we will pass in both track directions.

      If it still calculates a baseline in that case, we may want to scope to only one here

      Yanling Wang

      After debugging the specific edge case, I see the issue now, I've updated it to scope to only one here.

      File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
      Line 121, Patchset 4:<div class="grid-lanes lb">
      Alison Maher . resolved

      Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

      Yanling Wang

      I think this is the expected behavior based on grid baseline alignment calculation. When using "justify-items: last baseline", items are aligned by their last baseline, which can cause them to extend beyond their grid area boundaries and overlap with other items.
      For last baseline alignment (minor baseline group), the offset calculation is:
      `return available_size - baseline_delta - item_size;`

      The reference file demonstrates what grid produces in this scenario, and the test verifies that grid-lanes matches this behavior.

      Alison Maher

      If it matches grid, that seems reasonable, so no need to block on this comment. But just so I understand, it sounds like internally, the major axis is the first baseline, and the minor axis is the last baseline.

      So since these are using last baseline, we go down the minor baseline path. In this test, which items are aligned up with which? i.e. what are the alignment groups (I wouldn't have thought it's items in the same column). And why do some seem to align towards the left side of the container, and some on the right? Is it because of spanning items? Happy to chat offline to better understand this one

      Yanling Wang

      After our offline sync, this is the expected behavior. I've updated the test with larger track sizes and a different writing-mode to make the item alignment more visible.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Alison Maher
      • Ian Kilpatrick
      • Kurt Catti-Schmidt
      Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement is not satisfiedCode-Owners
        • requirement is not satisfiedCode-Review
        • 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: 7
        Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
        Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
        Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
        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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
        Gerrit-Comment-Date: Fri, 16 Jan 2026 21:57:33 +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>
        Comment-In-Reply-To: Yanling Wang <yanli...@microsoft.com>
        satisfied_requirement
        unsatisfied_requirement
        open
        diffy

        Alison Maher (Gerrit)

        unread,
        Jan 16, 2026, 5:32:49 PM (19 hours ago) Jan 16
        to Yanling Wang, Ian Kilpatrick, 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 Ian Kilpatrick, Kurt Catti-Schmidt and Yanling Wang

        Alison Maher voted and added 2 comments

        Votes added by Alison Maher

        Code-Review+1

        2 comments

        File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
        Line 570, Patchset 7 (Latest): LayoutUnit inline_baseline_offset =
        is_for_columns
        ? ComputeBaselineOffset(grid_lanes_item, track_collection,

        baseline_fragment, fragment,
        style.GetFontBaseline(), kForColumns,
        containing_rect.size.inline_size)
        : LayoutUnit();
        LayoutUnit block_baseline_offset =
        is_for_columns
        ? LayoutUnit()
        : ComputeBaselineOffset(grid_lanes_item, track_collection,

        baseline_fragment, fragment,
        style.GetFontBaseline(), kForRows,
        containing_rect.size.block_size);
        Alison Maher . unresolved

        nit: I might reorganize slightly like so:

        ```
        LayoutUnit inline_baseline_offset;
        LayoutUnit block_baseline_offset;
        if (is_for_columns) {
        inline_baseline_offset = ComputeBaselineOffset(grid_lanes_item, track_collection,

        baseline_fragment, fragment,
        style.GetFontBaseline(), kForColumns,
        containing_rect.size.inline_size);
              } else {
        block_baseline_offset = ComputeBaselineOffset(grid_lanes_item, track_collection,

        baseline_fragment, fragment,
        style.GetFontBaseline(), kForRows,
        containing_rect.size.block_size);
        ```

        And then might be worth a comment above to note that in grid-lanes, we only have tracks in one dimension, so baseline alignment is only supported in one dimension. Or something along those lines

        File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
        Line 121, Patchset 4:<div class="grid-lanes lb">
        Alison Maher . unresolved

        Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

        Yanling Wang

        I think this is the expected behavior based on grid baseline alignment calculation. When using "justify-items: last baseline", items are aligned by their last baseline, which can cause them to extend beyond their grid area boundaries and overlap with other items.
        For last baseline alignment (minor baseline group), the offset calculation is:
        `return available_size - baseline_delta - item_size;`

        The reference file demonstrates what grid produces in this scenario, and the test verifies that grid-lanes matches this behavior.

        Alison Maher

        If it matches grid, that seems reasonable, so no need to block on this comment. But just so I understand, it sounds like internally, the major axis is the first baseline, and the minor axis is the last baseline.

        So since these are using last baseline, we go down the minor baseline path. In this test, which items are aligned up with which? i.e. what are the alignment groups (I wouldn't have thought it's items in the same column). And why do some seem to align towards the left side of the container, and some on the right? Is it because of spanning items? Happy to chat offline to better understand this one

        Yanling Wang

        After our offline sync, this is the expected behavior. I've updated the test with larger track sizes and a different writing-mode to make the item alignment more visible.

        Alison Maher

        Great thanks! Is it possible to split into two tests (one with your updates, and one with the old behavior). I think the original is still an interesting edge case (just tough to reason about), so would be good to test in masonry, as well

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Ian Kilpatrick
        • Kurt Catti-Schmidt
        • Yanling Wang
        Submit Requirements:
        • requirement satisfiedCode-Coverage
        • requirement 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: 7
        Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
        Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
        Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
        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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
        Gerrit-Comment-Date: Fri, 16 Jan 2026 22:32:35 +0000
        Gerrit-HasComments: Yes
        Gerrit-Has-Labels: Yes
        Comment-In-Reply-To: Alison Maher <alm...@microsoft.com>
        Comment-In-Reply-To: Yanling Wang <yanli...@microsoft.com>
        satisfied_requirement
        unsatisfied_requirement
        open
        diffy

        Yanling Wang (Gerrit)

        unread,
        Jan 16, 2026, 6:13:30 PM (19 hours ago) Jan 16
        to Alison Maher, Ian Kilpatrick, 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, Ian Kilpatrick and Kurt Catti-Schmidt

        Yanling Wang added 2 comments

        File third_party/blink/renderer/core/layout/grid_lanes/grid_lanes_layout_algorithm.cc
        Line 570, Patchset 7: LayoutUnit inline_baseline_offset =

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

        nit: I might reorganize slightly like so:

        ```
        LayoutUnit inline_baseline_offset;
        LayoutUnit block_baseline_offset;
        if (is_for_columns) {
        inline_baseline_offset = ComputeBaselineOffset(grid_lanes_item, track_collection,
        baseline_fragment, fragment,
        style.GetFontBaseline(), kForColumns,
        containing_rect.size.inline_size);
        } else {
        block_baseline_offset = ComputeBaselineOffset(grid_lanes_item, track_collection,
        baseline_fragment, fragment,
        style.GetFontBaseline(), kForRows,
        containing_rect.size.block_size);
        ```

        And then might be worth a comment above to note that in grid-lanes, we only have tracks in one dimension, so baseline alignment is only supported in one dimension. Or something along those lines

        Yanling Wang

        Done

        File third_party/blink/web_tests/external/wpt/css/css-grid/grid-lanes/tentative/baseline/column-grid-lanes-item-baseline-004.html
        Line 121, Patchset 4:<div class="grid-lanes lb">
        Alison Maher . resolved

        Haven't looked deaply at this, but why in the ref do we get overlapping of items in this case?

        Yanling Wang

        I think this is the expected behavior based on grid baseline alignment calculation. When using "justify-items: last baseline", items are aligned by their last baseline, which can cause them to extend beyond their grid area boundaries and overlap with other items.
        For last baseline alignment (minor baseline group), the offset calculation is:
        `return available_size - baseline_delta - item_size;`

        The reference file demonstrates what grid produces in this scenario, and the test verifies that grid-lanes matches this behavior.

        Alison Maher

        If it matches grid, that seems reasonable, so no need to block on this comment. But just so I understand, it sounds like internally, the major axis is the first baseline, and the minor axis is the last baseline.

        So since these are using last baseline, we go down the minor baseline path. In this test, which items are aligned up with which? i.e. what are the alignment groups (I wouldn't have thought it's items in the same column). And why do some seem to align towards the left side of the container, and some on the right? Is it because of spanning items? Happy to chat offline to better understand this one

        Yanling Wang

        After our offline sync, this is the expected behavior. I've updated the test with larger track sizes and a different writing-mode to make the item alignment more visible.

        Alison Maher

        Great thanks! Is it possible to split into two tests (one with your updates, and one with the old behavior). I think the original is still an interesting edge case (just tough to reason about), so would be good to test in masonry, as well

        Yanling Wang

        Splited into two tests.

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Alison Maher
        • Ian Kilpatrick
        • Kurt Catti-Schmidt
        Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement satisfiedCode-Owners
          • requirement is not satisfiedCode-Review
          • 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: 8
          Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
          Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
          Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
          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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
          Gerrit-Comment-Date: Fri, 16 Jan 2026 23:13:19 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy

          Alison Maher (Gerrit)

          unread,
          Jan 16, 2026, 6:17:20 PM (18 hours ago) Jan 16
          to Yanling Wang, Ian Kilpatrick, 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 Ian Kilpatrick, Kurt Catti-Schmidt and Yanling Wang

          Alison Maher voted Code-Review+1

          Code-Review+1
          Open in Gerrit

          Related details

          Attention is currently required from:
          • Ian Kilpatrick
          • Kurt Catti-Schmidt
          • Yanling Wang
          Submit Requirements:
          • requirement satisfiedCode-Coverage
          • requirement satisfiedCode-Owners
          • requirement is not satisfiedCode-Review
          • 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: 8
          Gerrit-Owner: Yanling Wang <yanli...@microsoft.com>
          Gerrit-Reviewer: Alison Maher <alm...@microsoft.com>
          Gerrit-Reviewer: Ian Kilpatrick <ikilp...@chromium.org>
          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-Attention: Ian Kilpatrick <ikilp...@chromium.org>
          Gerrit-Comment-Date: Fri, 16 Jan 2026 23:17:06 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: Yes
          satisfied_requirement
          unsatisfied_requirement
          open
          diffy
          Reply all
          Reply to author
          Forward
          0 new messages