Title: CSS Grid Layout Module Level 3
Shortname: css-grid
Level: 3
Status: ED
Work Status: Exploring
Group: csswg
ED: https://drafts.csswg.org/css-grid-3/
Editor: Tab Atkins Jr., Google, http://www.xanthir.com/contact/, w3cid 42199
Editor: Elika J. Etemad / fantasai, Apple, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Mats Palmgren, Mozilla, mailto:mats@mozilla.com
Editor: Jen Simmons, Apple, http://jensimmons.com/
Editor: Brandon Stewart, Apple, https://brandonstewart.net
Abstract: This module introduces masonry layout as an additional layout mode for CSS Grid containers.
WPT Path Prefix: css/css-grid/masonry/tentative/
Markup Shorthands: css yes
Status Text: This specification represents two variations on the proposal for masonry layout. Feedback on the alternatives is welcome.

Introduction

This section is not normative. Grid Layout is a layout model for CSS that has powerful abilities to control the sizing and positioning of boxes and their contents. Grid Layout is optimized for 2-dimensional layouts: those in which alignment of content is desired in both dimensions.
An example of grid layout:
		     two rows of items,
		     the first being four items — the last of which spans both rows,
		     and the second being two items —
		     the first of which spans the first two columns —
		     plus the spanned item from the first row.
Representative Grid layout example
Although many layouts can be expressed with regular Grid Layout, restricting items into a grid in both axes also makes it impossible to express some common layouts on the Web. This module defines a layout system that removes that restriction so that items can be placed into Grid-like tracks in just one of the axes, while stacking them one after another in the other axis. Items are placed into the column (or row) with the most remaining space based on the layout size of the items placed so far. This module also extends CSS Grid with this new grid item placement strategy and CSS Box Alignment with new alignment features.

Background and Motivation

[=Masonry layout=], sometimes also called “waterfall layout”, is a common Web design pattern where a number of items-- commonly images or short article summaries-- are placed one by one into columns in a way that loosely resembles stone masonry. Unlike [[CSS-MULTICOL-1|multi-column layout]], where content is placed vertically in the first column until it must spills over to the second column, [=masonry layout=] selects a column for each new item such that it is generally closer to the top of the layout than items placed later.
The Pinterest search results page exemplifies this layout:
An example of masonry layout:
			          four columns of items,
			          each item is placed into the column with the smallest height so far.
Representative masonry layout example
Here, each item has a different height (depending on the content and the width of the column), and inspecting the DOM reveals (as the visual content itself gives no indication of ordering) that each item has been placed into the column with the smallest height so far.
This layout superficially looks similar to multi-column layout; but it has the advantage that scrolling down will naturally lead to "later" items in the layout (that is, those less relevant in the search results). It's not possible to achieve this layout using earlier CSS layout models, unless you know up-front how tall each item will be, or use JavaScript for content measurement or placement.

Alternative Syntax Proposals

The masonry layout feature of this specification is drafted with two different syntaxes to promote debate and discussion of these two alternatives.
Grid-integrated Option
In this syntax model, [=masonry layout=] is integrated into the [=grid layout=] model, re-using all of the 'grid-*' properties.
Grid-independent Option
In this syntax model, [=masonry layout=] is its own 'display' type, and has its own parallel set of 'masonry-*' properties.

Value Definitions

This specification follows the CSS property definition conventions from [[!CSS2]] using the value definition syntax from [[!CSS-VALUES-3]]. Value types not defined in this specification are defined in CSS Values & Units [[!CSS-VALUES-3]]. Combination with other CSS modules may expand the definitions of these value types. In addition to the property-specific values listed in their definitions, all properties defined in this specification also accept the CSS-wide keywords as their property value. For readability they have not been repeated explicitly.

Masonry Layout Model

Masonry layout lays out items into pre-defined tracks similar to [=grid layout=] in one axis (called the grid axis), but flows them freely similar to [=flex layout=] in the other (called the masonry axis). Similar to [=grid layout=] and unlike [=flex layout=], [=masonry layout=]’s auto-placement distributes items across the tracks to keep the lengths of those tracks as similar as possible. [=Grid items=] are formed and [=blockified=] exactly the same as in a regular [=grid container=]. All CSS properties work the same as in a regular [=grid container=] unless otherwise specified by this specification. For example, ''order'' can be used to specify a different layout order for the items. Note: Subgrid items are supported, but subgridding only occurs in the [=grid axis=]; see [[#subgrids]] for details. A masonry container is a box whose contents participate in [=masonry layout=]. A [=masonry container=] is a column masonry container if its [=masonry axis=] is the [=block axis=], or a row masonry container if its [=masonry axis=] is the [=inline axis=].
Establishing Masonry Containers
Grid-integrated Syntax Grid-independent Syntax Description
Column Masonry
					display: grid;
					grid-template-columns: 1fr 2fr 3fr;
					grid-template-rows: masonry;
				
					display: masonry;
					masonry-tracks: 1fr 2fr 3fr;
					masonry-direction: column;
				
Column masonry lays out items in columns,
					     but ordered across the columns,
					     placing each item in the then-shortest column.
Row Masonry
					display: grid;
					grid-template-rows: 1fr 2fr 3fr;
					grid-template-columns: masonry;
				
					display: masonry;
					masonry-tracks: 1fr 2fr 3fr;
					masonry-direction: row;
				
Row masonry lays out items in rows,
					     but ordered down across the rows,
					     placing each item in the then-shortest row.

Grid-integrated Option: Establishing Masonry Layout

Indicating the Masonry Axis: the ''grid-template-columns/masonry'' keyword for 'grid-template-columns'/'grid-template-rows'

		Name: grid-template-columns, grid-template-rows
		New values: masonry
		Initial: none
		Applies to: [=grid containers=]
		Inherited: no
		Percentages: refer to corresponding dimension of the content area
		Computed value: the keyword ''grid-template-columns/none'' or the keyword ''grid-template-columns/masonry'' or a [[computed track list]]
		Animation type: see [[css-grid-2#track-sizing|CSS Grid Level 2]]
	
[=Masonry layout=] can be applied to [=grid containers=] by specifying the value ''grid-template-columns/masonry'' for one of its axes, defining it as the [=masonry axis=]. Such [=grid containers=] are called [=masonry containers=]. If ''grid-template-columns/masonry'' is specified for both ''grid-template-columns'' and ''grid-template-rows'', then the [=used value=] for ''grid-template-columns'' is ''grid-template-columns/none'', and thus the [=inline axis=] will be the [=grid axis=].

Auto Flow Directions: the 'grid-auto-flow' property

	Name: grid-auto-flow
	Value: [ row | column | row-reverse | column-reverse ] || dense || wrap-reverse
	Initial: row
	Applies to: grid containers
	Inherited: no
	Percentages: n/a
	Computed value: specified keyword(s)
	Animation type: discrete
	

This specification extends the grid-auto-flow property to add row-reverse, column-reverse, and wrap-reverse, which reverse the directions of the [=auto-placement algorithm=]. In [=masonry layout=], the flow axis specified by ''grid-auto-flow'' is ignored: items are always placed by filling across the [=grid axis=]. ISSUE: Should that be the case, or should we follow the 'grid-auto-flow' axis always (so it would fill similar to flexbox, but with explicitly-sized tracks)?

Grid-independent Option: Establishing Masonry Layout

Establishing Masonry Containers: the ''masonry'' and ''inline-masonry'' 'display' values

	Name: display
	New values: masonry | inline-masonry
	
: masonry :: This value causes an element to generate a [=masonry container=] box that is [=block-level=] when placed in [=flow layout=]. : inline-masonry :: This value causes an element to generate a [=masonry container=] box that is [=inline-level=] when placed in [=flow layout=].

Masonry Track Direction: the 'masonry-direction' property

	Name: masonry-direction
	Value: row | column | row-reverse | column-reverse
	Initial: column
	Inherited: no
	Applies to: [=masonry containers=]
	Computed value: as specified
	Animation type: discrete
	
The 'masonry-direction' property specifies how items are placed in the [=masonry container=], by setting its [=masonry axis=] and direction.
: column :: The [=masonry container's=] [=masonry axis=] is its [=block axis=], and masonry layout starts from its [=block-start=] edge. : column-reverse :: The [=masonry container's=] [=masonry axis=] is its [=block axis=], and masonry layout starts from its [=block-end=] edge. : row :: The [=masonry container's=] [=masonry axis=] is its [=inline axis=], and masonry layout starts from its [=inline-start=] edge. : row-reverse :: The [=masonry container's=] [=masonry axis=] is its [=inline axis=], and masonry layout starts from its [=inline-end=] edge.
The [=masonry container's=] [=grid axis=] is perpendicular to its [=masonry axis=].

Masonry Cross Direction: the 'masonry-fill' property

	Name: masonry-fill
	Value: normal | reverse
	Initial: normal
	Inherited: no
	Applies to: [=masonry containers=]
	Computed value: as specified
	Animation type: discrete
	
'masonry-fill' determines what direction auto-placed items are laid out in when multiple tracks are tied for “shortest”.
: normal :: Ties are broken by filling the startmost track : reverse :: Ties are broken by filling the endmost track.

Masonry Flow Directions: the 'masonry-flow' shorthand

	Name: masonry-flow
	Value: <<'masonry-direction'>> || <<'masonry-fill'>>
	
The 'masonry-flow' property is a [=shorthand=] for the 'masonry-direction' and 'masonry-fill' properties.

Masonry Track Specification

In the [=grid axis=], the full power of [=grid layout=] is available for track specification: * Track sizes, line names, and areas can be specified on the [=masonry container=]’s [=grid axis=], just like in [=grid layout=]. * The [=explicit grid=] and [=implicit grid=] are formed in the same way as for a regular [=grid container=]. * Items can be [[#masonry-track-placement|placed]] against these grid templates just as in [=grid layout=]. However, auto-placed items contribute sizing to all tracks, not just the track into which they are ultimately placed; see [[#track-sizing]]. Note: This is because auto-placed items must be laid out as they are placed, so that each track knows how “full” it is (and therefore which track should receive the next auto-placed item); thus, the tracks themselves must already have a definite size so that the items know their [=available space=] during layout.

Grid-integrated Option: Declaring Masonry Track Templates: the 'grid-template-*' properties

The 'grid-template-*' and 'grid-auto-rows'/'grid-auto-columns' properties (and their shorthands) apply in the [=grid axis=] of the [=masonry container=] and establish tracks just as on regular [=grid containers=].

Grid-independent Option: Declaring Masonry Track Templates: the 'masonry-template-*' properties

Tracks in the [=grid axis=] of a [=masonry container=] are established with 'masonry-template-tracks', 'masonry-template-areas', and 'masonry-auto-tracks'.
	Name: masonry-template-tracks
	Value: <<'grid-template-columns'>>
	Initial: repeat(auto-areas, auto)
	Applies to: [=masonry containers=]
	Inherited: no
	Percentages: refer to correspodning dimension of the content area
	Computed value: by computed value type per item in the [=computed track list=]
	Animation type: if list lengths match, by [=computed value=] type; otherwise, discrete
	
'masonry-template-tracks' has the same syntax and interpretation as 'grid-template-columns', but a different initial value. (Instead of defaulting to no tracks, as in Grid Layout, it defaults to matching 'masonry-template-areas', if possible, or otherwise filling the [=masonry container=] with as many ''grid-template-columns/auto'' tracks as possible.)
	Name: masonry-template-areas
	Value: none | <>
	Initial: none
	Applies to: [=masonry containers=]
	Inherited: no
	Percentages: n/a
	Computed Value: the keyword ''masonry-template-values/none'' or a string
	Canonical Order: per grammar
	Animation type: discrete
	
'masonry-template-areas' has the same syntax and interpretation as 'grid-template-areas', except it only takes a single string defining one "row" of area names.
	Name: masonry-auto-tracks
	Value: <<'grid-auto-columns'>>
	Initial: auto
	Applies to: grid containers
	Inherited: no
	Percentages: refer to correspodning dimension of the content area
	Computed value: a [=computed track list=]
	Canonical order: per grammar
	Animation type:	if the list lengths match, by computed value type per item; discrete otherwise
	
'masonry-auto-tracks' has the same syntax and interpretation as 'grid-auto-columns'.

Subgrids

[=Subgridding=] allows nested [=masonry containers=] (and [=grid containers=]) to share track sizes. If the parent's corresponding axis is a [=grid axis=], the subgridded axis is taken from the parent container [[css-grid-2#subgrids|as specified for grid containers]]; if the parent's corresponding axis is a [=masonry axis=]...
Grid-integrated Syntax: ...the subgridded axis acts like ''masonry''. Note: If this results in ''grid-template/masonry'' in both axes, it is resolved as normal for [=masonry containers=] with double-axis ''grid-template/masonry'' templates, i.e. it acts like ''grid-template-columns: none; grid-template-rows: masonry''.

Grid-independent Syntax: ...the subgridded axis acts like ''grid-template/none''. In [=masonry layout=], auto-placed [=subgrids=] don't inherit any line names from their parent grid, because that would make the placement of the item dependent on layout results; but the subgrid's tracks are still aligned to the parent's tracks as usual.

Here's a subgrid example: ```css ``` ```html
1 2 3 subgrid.1 sub.2 s.3 4 5 6 7
```
The rendering of the subgrid example above.
Note how the subgrid's first item ("subgrid.1") contributes to the intrinsic size of the 2nd row in the parent grid. This is possible since the subgrid specified a definite position so we know which tracks it will occupy. Note also that trying to subgrid the parent's [=masonry axis=] results in the subgrid getting [=masonry layout=] in its [=inline axis=].
A [=subgrid=] that is a [=masonry container=] can be referred to as a submasonry.

Track Repetition: the ''repeat()'' notation

This specification introduces new keywords and masonry-specific behavior for the ''repeat()'' notation.

repeat(auto-areas)

The new auto-areas value for the ''repeat()'' notation represents the number of repetitions necessary for the total number of explicit tracks to match the 'grid-template-areas' / 'masonry-template-areas' value in effect in the corresponding axis. If multiple tracks are listed for the repetition, the final repetition is truncated as necessary to produce the correct number of tracks. Note: Unlike ''repeat()/auto-fill''-- which always repeats at least once and always repeats the track listing entirely-- the number of repetitions for ''repeat()/auto-areas'' can be zero (if there are already enough explicit tracks), and the final repetition can be partial. If 'grid-template-areas' / 'masonry-template-areas' is ''grid-template-areas/none'', this value behaves as ''auto-fill''. Note: This value applies both to regular [=grid containers=] and to [=masonry containers=].

repeat(auto-fit)

In [=masonry containers=] (as in regular [=grid containers=]) ''repeat()/auto-fit()'' acts like ''repeat()/auto-fill'', but with empty tracks [=collapsed tracks|collapsed=]. However, because placement occurs after track sizing, [=masonry containers=] use a heuristic to determine if a track will be occupied: * All tracks occupied by explicitly placed items are considered occupied. * With the sum of the spans of all auto-placed items as N, all unoccupied tracks up to the Nth such track are considered occupied. All tracks produced by the ''repeat()/auto-fit'' repetition and considered unoccupied by this heuristic are assumed “empty” and are [=collapsed tracks|collapsed=]. A [=collapsed track=] cannot accept placement of auto-placed items. Note: It is possible for an auto-placed item to be placed in a track when ''repeat()/auto-fill'' is used that would be collapsed if ''repeat()/auto-fit'' is used if there are auto-placed items with a span greater than 1 mixed with explicitly-placed items that leave gaps too small for the auto-placed items.

Grid Axis Track Sizing

Track sizing works the same as in [[css-grid-2#algo-track-sizing|CSS Grid]], except that when considering which items contribute to intrinsic sizes: * All items explicitly placed in that track contribute, and * All items with an [=automatic grid position=] contribute (regardless of whether they are ultimately placed in that track).
For example, suppose there are two columns in the [=grid axis=] and that * Items A, B, and C have no explicit position. * Item D is explicitly placed into the first column. In this case, items A, B, C, and D all contribute to sizing the first column, while only A, B, and C (and not D) contribute to the second column.
In the case of spanning items with an [=automatic grid position=], they are assumed to be placed at every possible start position, and contribute accordingly.
For example, suppose there are 5 columns in the [=grid axis=], with the middle having a fixed size of ''100px'' and the other two being ''grid-template/auto''-sized. For the purpose of track sizing, an item that spans 2 tracks and has an intrinsic contribution of 220px is essentially copied and assumed to exist: * At grid line 1, contributing 110px to each of the first two tracks. * At grid line 2, contributing 120px to the second track. * At grid line 3, contributing 120px to the fourth track. * At grid line 4, contributing 110px to the fourth and fifth tracks.
Note: This algorithm ensures that each track is at least big enough to accommodate every item that is ultimately placed in it, and does not create dependency cycles between placement and track sizing. However, depending on the variation in sizes, tracks could be larger than necessary: an exact fit is only guaranteed if all items are explicitly placed in the [=grid axis=] or all items are the same size (or matching multiples of that size, in the case of spanning items).

Subgrid Item Contributions

When sizing the tracks of either a regular [=grid container=] or a [=masonry container=], a [=submasonry=] has special handling of items that have an [=automatic grid position=]: * Any such item is placed into every possible grid track that could be spanned by the [=submasonry=]. (If the submasonry has a [=definite grid position=], thus only the spanned tracks; if it has an [=automatic grid position=], then all tracks in the parent grid.) * Any such item receives the largest margin/border/padding contribution of each edge at which it could hypothetically be placed. If the item spans the entire subgrid, it receives both. (See CSS Grid Layout §9.)

Optimized Track Sizing

Track sizing can be optimized by aggregating items that have the same span size and placement into a single virtual item as follows:
  1. Separate all the [=masonry items=] into item groups, according to the following properties: * the span of the item * the placement of the item, i.e. which tracks it is allowed to be placed in * the item's [=baseline-sharing group=] Note: For example, an item with span 2 placed in the second track will be in a different group than an item with span 2 that has an [=automatic grid position=].
  2. For each [=item group=], synthesize a virtual masonry item that has the maximum of every intrinsic size contribution among the items in that group. If the items apply [=baseline alignment=], determine the baselines of the [=virtual masonry item=] by placing all of its items into a single hypothetical grid track and finding their shared baseline(s) and shims. Increase the group's intrinsic size contributions accordingly.
  3. Place hypothetical copies of each [=virtual masonry item=] into the [=grid axis=] tracks in every position that the item could potentially occupy, and run the [[css-grid-2#algo-track-sizing|track sizing algorithm]] with those items. The resulting track sizes are the [=masonry container's=] track sizes.
Note: This optimization should give the same results as the track sizing description [[#track-sizing|above]]; if not this is an error, please report it to the CSSWG.

Masonry Placement

In the [=grid axis=], items can be explicitly placed into tracks and span them using the familiar [=grid-placement properties=]’ syntax. Auto-placement, however, uses the [[#masonry-layout-algorithm]], placing each item with an [=automatic grid position=] into the “shortest” masonry track available.
Here's a masonry layout example demonstrating placed and spanning items:
Rendering of the example above.
ISSUE: Need a better example!!!

Grid-integrated Option: Specifying Masonry Item Placement: the 'grid-column-*' and 'grid-row-*' properties

The 'grid-column-*' and 'grid-row-*' properties (and their shorthands) apply in the [=grid axis=] of the items and establish placement just as in regular [=grid layout=].

Grid-independent Option: Specifying Masonry Item Placement: the 'masonry-track-*' properties

Item placement in the [=grid axis=] of a [=masonry container=] is established with the masonry-track-start and masonry-track-end properties (and their masonry-track shorthand), whose syntax and interpretation are analogous to the 'grid-column-start' and 'grid-column-end' properties (and their 'grid-column' shorthand).

Placement Precision: the 'masonry-slack' property

	Name: masonry-slack
	Value: <>
	Initial: 1em
	Percentages: relative to the [=grid-axis=] [=content box=] size of the [=masonry container=]
	Inherited: no
	Applies to: [=masonry containers=]
	Computed value: a computed length
	Animation type: discrete
	
[=Masonry containers=] are filled by placing each [=masonry item=] in whichever [=masonry track=] is currently the least filled. When multiple tracks are tied for least-filled, placing the items in order looks good. But if tracks are only very slightly different heights, it can look strange to have them not fill in order, as the height differences aren't perceived as meaningfully different. The 'masonry-slack' property specifies what the threshold is for considering tracks to be “the same height”, causing them to fill in order.
: <> :: Specifies the tie threshold for the [=masonry container=]. Placement positions are considered to be equally good (“tied”) if they are within the specified distance from the shortest position. Note: The initial value is a “small” distance (''1em'') that is probably appropriate to represent “close enough”.
Issue: Is ''1em'' the right default?

Masonry Layout and Placement Algorithm

For each of the tracks in the [=grid axis=], keep a running position initialized to zero. Maintain also a auto-placement cursor, initially pointing to the first line. For each item in [=order-modified document order=]:
  1. If the item has a [=definite grid position=] in the [=grid axis=], use that placement. ISSUE: Should this also update the placement cursor? Otherwise, resolve its [=grid axis=] placement using these substeps:
    1. Starting at the first [=grid axis=] line in the [=implicit grid=], find the largest [=running position=] of the [=grid axis=] tracks that the item would span if it were placed at this line, and call this position max_pos.
    2. Increment the line number and repeat step 2 until the item would no longer fit inside the grid.
    3. Let |possible lines| be the line that resulted in the smallest max_pos, and all lines that result in a max_pos within the [=tie threshold=] of this max_pos.
    4. Choose the first line in |possible lines| greater than or equal to the [=auto-placement cursor=] as the item's position in the [=grid axis=]; or if there are none such, choose the first one.
    5. Update the [=auto-placement cursor=] to point to item's last line.
  2. Place the item in its [=grid axis=] tracks at the maximum of the [=running position=]s of the tracks it spans.
  3. Calculate the size of the item's containing block and then layout the item. Set the [=running position=] of the spanned [=grid axis=] tracks to max_pos + [=outer size=] + 'grid-gap'.
Note: This algorithm chooses the track that would result in the item being placed as highly as possible. If there are ties, it chooses the earliest such track, after the most recently placed item if possible (ensuring that it always “moves forward” even in the presence of ties). If placing items in reverse order (see 'grid-auto-flow'/'masonry-flow'), the algorithm is analogous but in reverse order.

Containing Block

The [=containing block=] for a [=grid item=] participating in [=masonry layout=] is formed by its [=grid area=] in the [=grid axis=] and the [=grid container=]'s [=content box=] in the [=masonry axis=].

Placement and Writing Modes

Note: Like all of [=grid layout=], masonry layout and placement is sensitive to the [=writing mode=]. For example, for ''direction: rtl'', items are placed right-to-left rather than left-to-right, whether the inline axis is a [=grid axis=] or a [=masonry axis=].
Here's a simple example using ''direction: rtl'' in the [=grid axis=]: ```css ``` ```html
1 2 3 4
```
Rendering of the ''direction: rtl'' example above.
Here's a simple example using ''direction: rtl'' in the [=masonry axis=]: ```css ``` ```html
1 2 3 4
```
Rendering of the ''direction: rtl'' example above.

Sizing Grid Containers

[[css-grid-2#intrinsic-sizes|Sizing Grid Containers]] works the same as for regular [=grid containers=] but with the following addendum for the [=masonry axis=]: The max-content size (min-content size) of a [=grid container=] in the [=masonry axis=] is the largest distance between the [=grid container's=] [=content-box=] [=start=] edge and the maximum [=margin-box=] end of all the items, when sized under a max-content constraint (min-content constraint).
Here's a simple example: ```css ``` ```html
1 2 3 4 5 6
```
Rendering of the [=grid container=] intrinsic sizing example above.

Alignment and Spacing

[[css-grid-2#gutters|Gutters]] are supported in both axes. In the [=masonry axis=], the gap is applied between the margin boxes of each pair of adjacent items. Margins do not collapse in either axis. In the [=grid axis=], [[css-grid-2#alignment|alignment]] works the same as in a regular [=grid container=]. In the [=masonry axis=], [[css-align-3#content-distribution|content-distribution]] is applied to the content as a whole, similarly to how it behaves in block containers. More specifically, the alignment subject is the masonry box, which is the smallest rectangle bounding the [=margin boxes=] of all the [=grid items=].
The extent of the [=masonry box=] is indicated by the dashed border. (Note that item 1 has a 5px bottom margin here.)
Note: There is only ever one alignment subject for these properties in the [=masonry axis=], so the unique 'align-content' / 'justify-content' values boil down to ''align-content/start'', ''align-content/center'', ''align-content/end'', and [=baseline alignment=]. (The behavior of ''align-content/normal'' and ''align-content/stretch'' is identical to ''align-content/start'', and the [=distributed alignment=] values behave as their [=fallback alignments=].) If the [=grid items=] overflow the [=grid container=]'s [=content box=] in the [=masonry axis=], then the [=masonry box=] will be larger than the [=grid container=]'s [=content box=]. ISSUE: Should alignment in the masonry axis do something more sophisticated? What should that be?

Baseline Alignment in the Masonry Axis

Item [=baseline alignment=] inside the [=grid axis=] tracks works as usual for a regular [=grid container=], and the [=grid container=]'s baseline is determined the same as for a regular [=grid container=] in that axis. [=Baseline alignment=] is not supported in the [=masonry axis=]. The first baseline set of the [=grid container=] in this axis is generated from the [=alignment baseline=] of the first [=grid item=] in the first occupied track, and the last baseline set from the last [=grid item=] placed. ISSUE: We could support baseline alignment in the first row. Do we want to? ISSUE: Should the last baseline come from the last lowest item placed instead?

Fragmentation

Fragmentation in the Masonry Axis

Each [=grid axis=] track is fragmented independently in the [=masonry axis=]. If a [=grid item=] is fragmented, or has a [=forced break=] before/after it, then the [=running position=] for the tracks that it spans in the [=grid axis=] are set to the size of the [=fragmentainer=] so that no further items will be placed in those tracks. An item that is split into multiple fragments retains its placement in the [=grid axis=] for all its fragments. A grid item that is pushed, however, is placed again by the next [=grid container=] fragment. Placement continues until all items are placed or pushed to a new fragment.
Here's an example illustrating fragmentation of a grid with masonry layout in its [=block axis=]. It renders like this:
Visualization of fragmentation in a [=block-axis=] [=masonry layout=].

Fragmentation in the Grid Axis

Fragmentation in the [=grid axis=] with [=masonry layout=] in the other axis is also supported. In this case the fragmentation behaves more like in a regular [=grid container=]; however, there's a separate step to determine which [=grid-axis=] track each item is placed into, before fragmentation occurs.
Here's an example illustrating fragmentation of a grid with [=masonry layout=] in its [=inline axis=]. In this case the breaks occurs between the [=grid-axis=] rows. It renders like this:
Visualization of fragmentation in the [=block axis=] with [=inline-axis=] [=masonry layout=].

Absolute Positioning

[[css-grid-1#abspos-items|Grid-aligned absolute-positioned descendants]] are supported in [=masonry containers=] just as for regular [=grid containers=]; however, in the [=masonry axis=] there exist only two lines (in addition to the ''grid-area/auto'' lines) for placement: * line 1 (line -2) corresponds to the start edge of the [=masonry box=] * line 2 (line -1) corresponds to the end edge of the [=masonry box=] ISSUE: It might be useful to define a static position in the [=masonry axis=]. Maybe it could defined as the max (or min?) current [=running position=] of the [=grid-axis=] tracks at that point? Or the end of the item before it?

Performance Notes

In general, masonry layout should have significantly better performance than the equivalent regular (2-axis) grid layout, particularly when the [=masonry axis=] is the [=block axis=] since the intrinsic sizing of grid rows is typically quite expensive. Any intrinsic track sizing in the [=grid axis=] should be cheaper too, because, typically, only a subset of items contribute to the intrinsic sizing in a masonry layout, contrary to a 2-axis grid where all items spanning an intrinsically-sized track contribute. Stretched items do a second layout with the new size (when it actually changed) so this can be costly if there are a huge amount of stretched items that each contains a lot of content. Especially nested stretched masonry layouts should be avoided unless they are small/trivial. Advisement: This can be ameliorated by the author by opting out from the stretching on most items though, e.g. specifying ''justify/align-items:start'' and then opting in for just a few items with ''justify/align-self:stretch'' to let those items fill the [=masonry axis=]. (This performance analysis is from a Gecko perspective, but I suspect there's some truth to it for other layout engines as well.)

Graceful Degradation

Typically, a masonry design can be expected to degrade quite nicely in a UA that supports Grid layout but not masonry layout if the 'grid'/'grid-template' shorthands are avoided and the longhands are used instead. e.g. ```css grid-template-rows: masonry; /* ignored by UAs that don't support it */ grid-template-columns: 150px 100px 50px; ```
Here's an example to illustrate this. It's a layout with three columns, but will have "more gaps" in the [=block axis=] if the UA doesn't support masonry layout. Here's what it looks like with Masonry support for comparison:
Rendering of the example in a UA with Masonry support.

Acknowledgements

Thanks goes to Cameron McCormack who wrote a masonry layout explainer document (from which I lifted the Background chapter) and presented it to the CSSWG. Thanks also to everyone who provided feedback on the initial proposal for this feature.