diff --git a/layout/docs/css-grid-3/Overview.bs b/layout/docs/css-grid-3/Overview.bs new file mode 100644 index 000000000000..acd659c86655 --- /dev/null +++ b/layout/docs/css-grid-3/Overview.bs @@ -0,0 +1,606 @@ +
+Title: CSS Masonry Layout Module
+Shortname: css-grid-3
+Status: LS
+Work Status: Testing
+Level: none
+URL: https://drafts.csswg.org/css-grid-3/
+Editor: Mats Palmgren, Mozilla, mailto:mats@mozilla.com
+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
+
+ + +

+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. It extends CSS Grid with this new grid item placement strategy and CSS Box Alignment with new alignment features. + +

+Background and Motivation

+ +Masonry 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, so-called because it resembles stone masonry. Unlike regular multi-column layout, where items are placed vertically in the first column until they must spill 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. + +An advantage to using this layout over regular multi-column layout is that the masonry layout container height grows as more items are placed into it, as a balancing multi-column layout would, but the effect for the reader is that scrolling down will naturally lead to "later" items in the layout (that is, those less relevant in the search results). + +Achieving this layout without knowing upfront how tall each item will be is currently not possible without using script. + +

+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 keywords as their property value. + For readability they have not been repeated explicitly. + +

+Masonry Layout

+ + +Masonry layout is supported for [=grid containers=] by specifying the value ''grid-template-columns/masonry'' for one of its axes. This axis is called the masonry axis, and the other axis is called the grid axis. + +
+	Name: grid-template-columns, grid-template-rows
+	Value: none | <> | <> | subgrid <>? | 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
+
+ +This allows us to use the full power of CSS Grid in the [=grid axis=]. Line names and track sizes can be specified and grid items can be placed into the tracks and span them using 'grid-column' / 'grid-row' as usual. The CSS Box Alignment properties works the same as in a regular [=grid container=] in this axis. In the [=masonry axis=] however, items are laid out one after another using the [[#masonry-layout-algorithm]]. + +
+Here's a masonry layout example demonstrating placed and spanning items: + +
+ +
Rendering of the example above.
+
+
+ +Subgrid grid items are supported but subgridding only occurs in the [=grid container's=] [=grid axis=], see [[#subgrids]] for details. + +If ''grid-template-columns/masonry'' is specified in both axes then the inline-axis will behave as ''grid-template-columns/none'' and it will thus be the [=grid axis=]. + +Grid items are formed and [=blockified=] exactly the same as in a regular [=grid container=]. + +All CSS properties works 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. + +

+Line Name Resolution

+ +
Grid item line name resolution works the same as if ''grid-template-columns/masonry'' were replaced with ''grid-template-columns/none'', i.e. line names are resolved in both axes. The line name resolution works exactly is in CSS Grid. + +

+Grid Item Placement

+ +Grid items are placed using these steps: +
    +
  1. Place the items as if the [=masonry axis=] had ''grid-template-columns/none'' specified in that axis. +
  2. Items that were placed at the first (hypothetical) implicit track in the [=masonry axis=] after step 1 keep their placement in both axes as their final placement. They will be laid out first in each [=grid axis=] track and their [=grid axis=] placement is considered definite henceforth. All other items ignore their placement from step 1. Any item with with a specified definite placement in the [=masonry axis=] that doesn't result in it being placed at the first implicit line in the [=masonry axis=] will be treated as having 'auto'-placement in that axis. +
  3. Place items using the Masonry layout algorithm below. +
+ +(The reason for step 1 above is to determine which items contribute to intrinsic track sizing in the [=grid axis=], see Track sizing below.) + +

+Masonry Layout Algorithm

+ +Items are placed in order-modifed document order but items with a definite placement are placed before items with an indefinite position (as in regular grid layout). For each of the tracks in the [=grid axis=], keep a running position initialized to zero. For each item that was placed at line 1 in the [=masonry axis=] in Grid Item Placement step 1 above: +
    +
  1. position the item at the content edge of the grid container in the [=masonry axis=] and at its start track in the [=grid axis=]
  2. +
  3. calculate the size of the containing block and then layout the item. Then calculate its resulting margin-box in the [=masonry axis=]. Set the [=running position=] of the [=grid axis=] tracks the item spans to the maximum of margin-box-end + grid-gap and the current [=running position=] of those tracks. +
+ +Note: This means that items with a definite placement at line 1 in the [=masonry axis=] by Grid Item Placement step 1 can be made to intentionally overlap. + +The remaining items get their final placement using the following steps: +
    +
  1. If the item has an indefinite placement in the [=grid axis=] then resolve its definite placement in the [=grid axis=] using these substeps: +
      +
    1. starting at the first [=grid axis=] line in the implicit grid...
    2. +
    3. find the largest [=running position=] of the [=grid axis=] tracks that the item would span if it were placed at this line, call this position max_pos
    4. +
    5. increment the line number and repeat step 2 until the item would no longer fit inside the grid
    6. +
    7. pick the line that resulted in the smallest max_pos as the item's definite placement in the [=grid axis=]
    8. +
    + Otherwise, a definite placement in the [=grid axis=] is honored the same as in a regular grid. +
  2. +
  3. position the item at its [=grid axis=] start track and the maximum of the [=running position=]s of the tracks it spans +
  4. calculate the size of the item's containing block and then layout the item. Then calculate its resulting margin-box in the [=masonry axis=]. Set the [=running position=] of the [=grid axis=] tracks the item spans to max_pos + margin-box-end + grid-gap. +
+ +The Masonry Layout Algorithm above can be modified in two ways, using the new 'masonry-auto-flow' property: + +
+	Name: masonry-auto-flow
+	Value: [ pack | next ] || [definite-first | ordered ]
+	Initial: pack
+	Applies to: [=grid containers=] with masonry layout
+	Inherited: no
+	Percentages: n/a
+	Computed value: specified keyword(s)
+	Animation type: discrete
+
+ + +First, picking definite items first for placement can be inhibited by specifying the ''masonry-auto-flow/ordered'' keyword so that a plain order-modifed document order is used instead. Second, instead of placing the items in the track(s) with the most remaining space as described above we can place them one after another in the [=grid axis=] by specifying the ''masonry-auto-flow/next'' keyword, for example: + +
+```css + +``` +```html +
+ 1 + 2 + 3 + 4 +
+``` + +
+ +
Rendering of the ''masonry-auto-flow: next'' example above.
+
+ +(Without ''masonry-auto-flow: next'', item 4 would be placed below item 2.) + +
+ +

+Containing Block

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

+Track sizing

+ +The Track Sizing Algorithm works as usual in the [=grid axis=], except only the subset of items with a definite placement in the [=grid axis=], or which span all tracks, contribute to the intrinsic sizing. This makes the first implicit line in the [=masonry axis=] special since those items will contribute to the intrinsic sizing even if they were 'auto'-placed in the [=grid axis=]. Other 'auto'-placed items don't contribute since which track they end up in depends on layout results; unless they span all tracks in which case there is only one possible placement and thus its placement is independent of layout results. + +

+repeat(auto-fit)

+ +''grid-template-rows/repeat(auto-fit)'' behaves as ''grid-template-rows/repeat(auto-fill)'' when the other axis is a [=masonry axis=]. The reason for this is that ''grid-row/auto''-placed items depend on the layout size of its siblings. Removing empty tracks after layout wouldn't be possible in most cases since it might affect any intrinsic track sizes. Even if all track sizes are definite the containing block size could change for grid-aligned abs.pos. descendants. This makes ''grid-template-rows/repeat(auto-fit)'' impossible to support in a grid container with masonry layout. + +

+The Implicit Grid +

+The implicit grid is formed in the same way as for a regular grid container. However, it's only used in the [=grid axis=]. The flow axis specified by ''grid-auto-flow'' is ignored — items are always placed by filling the [=grid axis=] (note that the ''grid-auto-flow/dense'' keyword does have an effect though in determining which items end up at line 1 in the [=masonry axis=], in [[#grid-item-placement]] step 1). ''direction:rtl'' reverses the grid if the inline-axis is the [=grid axis=] (as usual for a regular grid container) and it makes items flow from right to left if the inline-axis is the [=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

+ +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

+ +Gutters are supported in both axes. In the [=masonry axis=] the gap is applied between each pair of adjacent items margin-box. Margins do not collapse in either axis. + +Alignment works the same as in a regular [=grid container=] in the [=grid axis=]. + +Content Distribution in the [=masonry axis=] is applied to the content as a whole, same as for block containers. More specifically, the alignment subject is the masonry box, which is the area formed by the content-box edge of the [=grid container=] to the margin-box end edge of the item that is the furthest away in the [=masonry axis=], as indicated by the dashed border here: + +
+ +
+ The extent of the [=masonry box=] is indicated by the dashed border. + (Note that item 1 has a 5px bottom margin here.) +
+
+ + +Note that 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'', ''align-content/stretch'' and [=baseline alignment=]. (''align-content/normal'' behaves as ''align-content/stretch'' as usual for [=grid containers=]). In the figure above the [=grid container=] has ''align-content: start''. By default, the [=masonry box=] is the same as the [=grid container=]'s content-box due to being stretched. + +

+The align-tracks and justify-tracks Properties +

+ +This specification adds two new properties to align the items in the [=masonry axis=] for each individual [=grid axis=] track: + +
>
+	Name: align-tracks
+	Value: [normal | <> | <> | <>? <>]#
+	Initial: normal
+	Applies to: [=grid containers=] with masonry layout in their block axis
+	Inherited: no
+	Percentages: n/a
+	Computed value: specified keyword(s)
+	Animation type: discrete
+
+ +
+	Name: justify-tracks
+	Value: [normal | <> | <>? [ <> | left | right ] ]#
+	Initial: normal
+	Applies to: [=grid containers=] with masonry layout in their inline axis
+	Inherited: no
+	Percentages: n/a
+	Computed value: specified keyword(s)
+	Animation type: discrete
+
+ +Note: These values are the same as for 'align-content' / 'justify-content', but here we accept multiple values in a comma-separated list. + +Unlike 'align-content' / 'justify-content', ''align-tracks/normal'' behaves as ''align-tracks/start'' for these properties. So the default rendering is the expected packed masonry layout as shown in the top left corner in the example below. When multiple values are specified the first track in the [=grid axis=] uses the first value, the second track uses the second value, etc. If there are fewer values than tracks then the last value is used for the remaining tracks. If there are more values than tracks then the remaining values have no effect on the rendering. + +
+ Here's a testcase that demonstrates a few 'align-tracks' alignment possibilities. + +
+ +
+ The rendering of the ''align-tracks'' example above. +
+
+
+ +

+Stretch Alignment in the Masonry Axis

+ +''align-tracks/stretch'' will stretch the items in the [=masonry axis=] for each track separately to fill the content-box. Any item can opt out from stretching by setting ''align-self'' / ''justify-self'' to something other than ''align-self/normal'' or ''align-self/stretch'' in the relevant axis. Items with a [=definite size=] don't stretch and items with an ''margin/auto'' margin in the [=masonry axis=] stretch by increasing its margin(s) instead of its content-box size. An item only grows up to its max size. + +
+Here's a testcase that demonstrates stretching items in the [=masonry axis=]. +
+ +
+ Visualization of the ''align-tracks: stretch'' example above. +
+
+ +Only the purple items have ''height/auto'' height, so they are the ones that may grow by default. A few items worth noting: item 4 has ''max-height: 40px'' so it only grows up to that size and then the other items in its track picks up the remaining size. Item 16 opts out from resizing by setting ''align-self: end''. Item 18 has ''margin-top/bottom: auto'' so it's centered in its allotted space instead of growing. Item 20 has ''margin-top: auto'' so it's aligned to the end while its top-margin grows. +
+ +
+Here's the corresponding testcase with a masonry inline-axis instead. +
+ +
+ Visualization of the ''justify-tracks: stretch'' example above. +
+
+
+ +

+Individual Track Alignment in the Masonry Axis

+ +''align-tracks'' / ''justify-tracks'' values can be specified per track. + +
+Here's an example to illustrate this. Note that the 'align-tracks' value intentionally has one value less than the number of tracks to illustrate that the remaining track(s) use the last value (i.e. the right-most track also uses ''align-tracks/space-evenly''). (''align-tracks/baseline'' values are also supported but excluded in this test, see [[#masonry-axis-baseline-alignment]] for a description how that works with examples.) +
+ +
+ Rendering of the ''align-tracks'' alignment example above. +
+
+
+ +

+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 supported also in the [=masonry axis=], on the first and last item in each track (but not on items "in the middle" of the track). Only tracks with the 'align-tracks' / 'justify-tracks' values ''align-tracks/start'', ''align-tracks/end'' or ''align-tracks/stretch'', support baseline alignment. There are four different sets of [=baseline-sharing groups=]: + +
    +
  1. the first item in each ''align-tracks/start'' track + the first item in each ''align-tracks/stretch'' track +
  2. the last item in each ''align-tracks/start'' track +
  3. the first item in each ''align-tracks/end'' track +
  4. the last item in each ''align-tracks/end'' track + the last item in each ''align-tracks/stretch'' track +
+ +Each of those sets can have a [=first baseline set=] and a [=last baseline set=], resulting in eight unique baseline sets in the [=masonry axis=]. + +ISSUE: specify how the grid container's first(last) baseline in the [=masonry axis=] is determined + +
+Here's an example illustrating all eight possibilities. +(The example uses two separate [=grid containers=] to illustrate the first ("F") and last ("L") baseline sets to avoid cluttering the illustration, but it is possible to use all eight sets in the same container.) The aligned baselines are indicated with red color. Note that the tracks that are attached to the end side of the [=masonry box=] adjust the padding (or margin in the case of 'align-self') on the end side, whereas tracks attached to the start side adjust the start padding/margin. (only 'align-content' is used in this example, which adjusts the padding, since it's easier to see the baseline adjustment. 'align-self' can also be used, or a mix of the two, as usual.) +
+ +
+ The rendering of the example above. +
+
+
+ + +ISSUE: this needs more details about edge cases, caveat about misalignment in stretch, etc + +Advisement: Authors are advised to be careful with using alignment values other than ''align-tracks/start'' when some items span more than one track, because it's easy to cause items to unintentionally overlap in this case. + +ISSUE: can we make stretch alignment (at least) smarter so that we avoid overlapping spanning items in a few more cases that would be useful to authors? + +

+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 which [=grid-axis=] track each item is placed into occurs as a separate step upfront 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. +
+
+
+ + +

+Subgrids

+ +Masonry layout is supported also in [=subgrids=] (e.g. ''grid: subgrid / masonry''). However, only a parent grid axis can be subgridded in the normal sense. A subgrid axis with a parent [=masonry axis=] will behave as ''grid/masonry'', unless the subgrid's other axis is also ''grid/masonry'' in which case it behaves as ''grid/none'' (a [=grid container=] can only have one [=masonry axis=]). ''grid-column/auto''-placed subgrids don't inherit any line names from their parent grid because that would make the placement of the subgrid's grid items dependent on layout results, but subgrid's tracks are 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 placement 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. +
+ + +

+Absolute Positioning

+ + +Grid-aligned absolute-positioned descendants are supported. In the [=masonry axis=] all [=grid positions=] except line 1 are treated as 'auto'. Line 1 in the [=masonry axis=] corresponds to the start of the [=masonry box=] (the content-box start edge usually) and 'auto' uses the [=grid container=] padding edge as usual. The [=containing block=] is the extent of the tracks the item spans in the [=grid axis=] and the position of line 1 and the padding-box edge in the [=masonry axis=]. + +ISSUE: It might be useful to define a static position in the [=masonry axis=] though, given that we only have a one line in that axis to align to. Maybe it could defined as the max (or min?) current [=running position=] of the [=grid-axis=] tracks at that point? + +ISSUE: It would also be useful to be able to align the [=masonry box=] end edge somehow, but for that we need a way to address the end line in an implicit grid, or could we just use any non-auto line number other than 1 to indicate the end line given that we don't really have any lines in this axis other than line 1? + +

+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. That said, ''justify/align-tracks: stretch'' specifically adds a cost proportionate to the number of items that are resized. (Note that ''align-tracks/stretch'' isn't the default value for these properties though.) 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=]. Other 'justify-tracks' / 'align-tracks' values such as ''align-self/center'', ''align-self/end'' and '<>' (other than ''align-self/stretch'') shouldn't be a problem though since they just reposition the items which is fast. (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. diff --git a/layout/docs/css-grid-3/Overview.html b/layout/docs/css-grid-3/Overview.html new file mode 100644 index 000000000000..38781b9ca61b --- /dev/null +++ b/layout/docs/css-grid-3/Overview.html @@ -0,0 +1,3659 @@ + + + + CSS Masonry Layout Module + + + + + + + + + + + + + +
+

+

CSS Masonry Layout Module

+

Living Standard,

+
+
+
This version: +
https://drafts.csswg.org/css-grid-3/ +
Issue Tracking: +
Inline In Spec +
Editor: +
(Mozilla) +
+
+
+ +
+
+
+

Abstract

+

This module introduces masonry layout as an additional layout mode for CSS Grid containers.

+
+
+ +
+

1. 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. It extends CSS Grid with this new grid item placement strategy and CSS Box Alignment with new alignment features.

+

1.1. Background and Motivation

+

Masonry 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, so-called because it resembles stone masonry. Unlike regular multi-column layout, where items are placed vertically in the first column until they must spill 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.

+

An advantage to using this layout over regular multi-column layout is that the masonry layout container height grows as more items are placed into it, as a balancing multi-column layout would, but the effect for the reader is that scrolling down will naturally lead to "later" items in the layout (that is, those less relevant in the search results).

+

Achieving this layout without knowing upfront how tall each item will be is currently not possible without using script.

+

1.2. 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 keywords as their property value. + For readability they have not been repeated explicitly.

+

2. Masonry Layout

+

Masonry layout is supported for grid containers by specifying the value masonry for one of its axes. This axis is called the masonry axis, and the other axis is called the grid axis.

+ + + + + + + + + + + +
Name: + grid-template-columns, grid-template-rows +
Value: + none | <track-list> | <auto-track-list> | subgrid <line-name-list>? | masonry +
Initial: + none +
Applies to: + grid containers +
Inherited: + no +
Percentages: + refer to corresponding dimension of the content area +
Computed value: + the keyword none or the keyword masonry or a computed track list +
Canonical order: + per grammar +
Animation type: + see CSS Grid +
+

This allows us to use the full power of CSS Grid in the grid axis. Line names and track sizes can be specified and grid items can be placed into the tracks and span them using grid-column / grid-row as usual. The CSS Box Alignment properties works the same as in a regular grid container in this axis. In the masonry axis however, items are laid out one after another using the § 2.3 Masonry Layout Algorithm.

+
+ Here’s a masonry layout example demonstrating placed and spanning items: +
+ +
Rendering of the example above.
+
+
+

Subgrid grid items are supported but subgridding only occurs in the grid container’s grid axis, see § 9 Subgrids for details.

+

If masonry is specified in both axes then the inline-axis will behave as none and it will thus be the grid axis.

+

Grid items are formed and blockified exactly the same as in a regular grid container.

+

All CSS properties works 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.

+

2.1. Line Name Resolution

+

Grid item line name resolution works the same as if masonry were replaced with none, i.e. line names are resolved in both axes. The line name resolution works exactly is in CSS Grid.

+

2.2. Grid Item Placement

+

Grid items are placed using these steps:

+
    +
  1. Place the items as if the masonry axis had none specified in that axis. +
  2. Items that were placed at the first (hypothetical) implicit track in the masonry axis after step 1 keep their placement in both axes as their final placement. They will be laid out first in each grid axis track and their grid axis placement is considered definite henceforth. All other items ignore their placement from step 1. Any item with with a specified definite placement in the masonry axis that doesn’t result in it being placed at the first implicit line in the masonry axis will be treated as having auto-placement in that axis. +
  3. Place items using the Masonry layout algorithm below. +
+

(The reason for step 1 above is to determine which items contribute to intrinsic track sizing in the grid axis, see Track sizing below.)

+

2.3. Masonry Layout Algorithm

+

Items are placed in order-modifed document order but items with a definite placement are placed before items with an indefinite position (as in regular grid layout). For each of the tracks in the grid axis, keep a running position initialized to zero. For each item that was placed at line 1 in the masonry axis in Grid Item Placement step 1 above:

+
    +
  1. position the item at the content edge of the grid container in the masonry axis and at its start track in the grid axis +
  2. calculate the size of the containing block and then layout the item. Then calculate its resulting margin-box in the masonry axis. Set the running position of the grid axis tracks the item spans to the maximum of margin-box-end + grid-gap and the current running position of those tracks. +
+

Note: This means that items with a definite placement at line 1 in the masonry axis by Grid Item Placement step 1 can be made to intentionally overlap.

+

The remaining items get their final placement using the following steps:

+
    +
  1. + If the item has an indefinite placement in the grid axis then resolve its definite placement in the grid axis using these substeps: +
      +
    1. starting at the first grid axis line in the implicit grid... +
    2. find the largest running position of the grid axis tracks that the item would span if it were placed at this line, call this position max_pos +
    3. increment the line number and repeat step 2 until the item would no longer fit inside the grid +
    4. pick the line that resulted in the smallest max_pos as the item’s definite placement in the grid axis +
    + Otherwise, a definite placement in the grid axis is honored the same as in a regular grid. +
  2. position the item at its grid axis start track and the maximum of the running positions of the tracks it spans +
  3. calculate the size of the item’s containing block and then layout the item. Then calculate its resulting margin-box in the masonry axis. Set the running position of the grid axis tracks the item spans to max_pos + margin-box-end + grid-gap. +
+

The Masonry Layout Algorithm above can be modified in two ways, using the new masonry-auto-flow property:

+ + + + + + + + + + + +
Name: + masonry-auto-flow +
Value: + [ pack | next ] || [definite-first | ordered ] +
Initial: + pack +
Applies to: + grid containers with masonry layout +
Inherited: + no +
Percentages: + n/a +
Computed value: + specified keyword(s) +
Canonical order: + per grammar +
Animation type: + discrete +
+

First, picking definite items first for placement can be inhibited by specifying the ordered keyword so that a plain order-modifed document order is used instead. Second, instead of placing the items in the track(s) with the most remaining space as described above we can place them one after another in the grid axis by specifying the next keyword, for example:

+
+ +
<style>
+.grid {
+  display: inline-grid;
+  grid: masonry / repeat(3, 2ch);
+  border: 1px solid;
+  masonry-auto-flow: next;
+}
+
+item { background: silver }
+item:nth-child(2n+1) {
+  background: pink;
+  height: 4em;
+}
+</style>
+
+
<div class="grid">
+  <item>1</item>
+  <item>2</item>
+  <item>3</item>
+  <item>4</item>
+</div>
+
+
+ +
Rendering of the masonry-auto-flow: next example above.
+
+

(Without masonry-auto-flow: next, item 4 would be placed below item 2.)

+
+

3. Containing Block

+

The containing block for a grid item is formed by its grid area in the grid axis and the grid container’s content-box in the masonry axis.

+

4. Track sizing

+

The Track Sizing Algorithm works as usual in the grid axis, except only the subset of items with a definite placement in the grid axis, or which span all tracks, contribute to the intrinsic sizing. This makes the first implicit line in the masonry axis special since those items will contribute to the intrinsic sizing even if they were auto-placed in the grid axis. Other auto-placed items don’t contribute since which track they end up in depends on layout results; unless they span all tracks in which case there is only one possible placement and thus its placement is independent of layout results.

+

4.1. repeat(auto-fit)

+

repeat(auto-fit) behaves as repeat(auto-fill) when the other axis is a masonry axis. The reason for this is that auto-placed items depend on the layout size of its siblings. Removing empty tracks after layout wouldn’t be possible in most cases since it might affect any intrinsic track sizes. Even if all track sizes are definite the containing block size could change for grid-aligned abs.pos. descendants. This makes repeat(auto-fit) impossible to support in a grid container with masonry layout.

+

5. The Implicit Grid

+ The implicit grid is formed in the same way as for a regular grid container. However, it’s only used in the grid axis. The flow axis specified by grid-auto-flow is ignored — items are always placed by filling the grid axis (note that the dense keyword does have an effect though in determining which items end up at line 1 in the masonry axis, in § 2.2 Grid Item Placement step 1). direction:rtl reverses the grid if the inline-axis is the grid axis (as usual for a regular grid container) and it makes items flow from right to left if the inline-axis is the masonry axis. +
+ Here’s a simple example using direction: rtl in the grid axis: +
<style>
+.grid {
+  display: inline-grid;
+  direction: rtl;
+  grid: masonry / repeat(4, 2ch);
+  border: 1px solid;
+}
+
+item { background: silver }
+item:nth-child(2n+1) {
+  background: pink;
+  height: 4em;
+}
+</style>
+
+
<div class="grid">
+  <item>1</item>
+  <item style="grid-column:span 2">2</item>
+  <item>3</item>
+  <item>4</item>
+</div>
+
+
+ +
Rendering of the direction: rtl example above.
+
+
+
+ Here’s a simple example using direction: rtl in the masonry axis: +
<style>
+.grid {
+  display: inline-grid;
+  direction: rtl;
+  width: 10ch;
+  column-gap: 1ch;
+  grid: repeat(4, 2em) / masonry;
+  border: 1px solid;
+}
+
+item { background: silver }
+item:nth-child(2n+1) {
+  background: pink;
+  width: 4ch;
+}
+</style>
+
+
<div class="grid">
+  <item>1</item>
+  <item style="grid-row:span 2">2</item>
+  <item>3</item>
+  <item>4</item>
+</div>
+
+
+ +
Rendering of the direction: rtl example above.
+
+
+

6. Sizing Grid Containers

+

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: +
<style>
+.grid {
+  display: inline-grid;
+  grid: masonry / 50px 100px auto;
+  grid-gap: 10px;
+  border: 1px solid;
+}
+item { background: silver; margin: 5px; }
+</style>
+
+
<div class="grid">
+  <item style="border:10px solid">1</item>
+  <item>2</item>
+  <item>3</item>
+  <item style="height:50px">4</item>
+  <item>5</item>
+  <item>6</item>
+</div>
+
+
+ +
Rendering of the grid container intrinsic sizing example above.
+
+
+

7. Alignment and Spacing

+

Gutters are supported in both axes. In the masonry axis the gap is applied between each pair of adjacent items margin-box. Margins do not collapse in either axis.

+

Alignment works the same as in a regular grid container in the grid axis.

+

Content Distribution in the masonry axis is applied to the content as a whole, same as for block containers. More specifically, the alignment subject is the masonry box, which is the area formed by the content-box edge of the grid container to the margin-box end edge of the item that is the furthest away in the masonry axis, as indicated by the dashed border here:

+
+ +
The extent of the masonry box is indicated by the dashed border. + (Note that item 1 has a 5px bottom margin here.)
+
+

Note that 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 start, center, end, stretch and baseline alignment. (normal behaves as stretch as usual for grid containers). In the figure above the grid container has align-content: start. By default, the masonry box is the same as the grid container's content-box due to being stretched.

+

7.1. The align-tracks and justify-tracks Properties

+

This specification adds two new properties to align the items in the masonry axis for each individual grid axis track:

+ + + + + + + + + + + +
Name: + align-tracks +
Value: + [normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>]# +
Initial: + normal +
Applies to: + grid containers with masonry layout in their block axis +
Inherited: + no +
Percentages: + n/a +
Computed value: + specified keyword(s) +
Canonical order: + per grammar +
Animation type: + discrete +
+ + + + + + + + + + + +
Name: + justify-tracks +
Value: + [normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ] ]# +
Initial: + normal +
Applies to: + grid containers with masonry layout in their inline axis +
Inherited: + no +
Percentages: + n/a +
Computed value: + specified keyword(s) +
Canonical order: + per grammar +
Animation type: + discrete +
+

Note: These values are the same as for align-content / justify-content, but here we accept multiple values in a comma-separated list.

+

Unlike align-content / justify-content, normal behaves as start for these properties. So the default rendering is the expected packed masonry layout as shown in the top left corner in the example below. When multiple values are specified the first track in the grid axis uses the first value, the second track uses the second value, etc. If there are fewer values than tracks then the last value is used for the remaining tracks. If there are more values than tracks then the remaining values have no effect on the rendering.

+
+ Here’s a testcase that demonstrates a few align-tracks alignment possibilities. +
+ +
The rendering of the align-tracks example above.
+
+
+

7.2. Stretch Alignment in the Masonry Axis

+

stretch will stretch the items in the masonry axis for each track separately to fill the content-box. Any item can opt out from stretching by setting align-self / justify-self to something other than normal or stretch in the relevant axis. Items with a definite size don’t stretch and items with an auto margin in the masonry axis stretch by increasing its margin(s) instead of its content-box size. An item only grows up to its max size.

+
+ Here’s a testcase that demonstrates stretching items in the masonry axis. +
+ +
Visualization of the align-tracks: stretch example above.
+
+

Only the purple items have auto height, so they are the ones that may grow by default. A few items worth noting: item 4 has max-height: 40px so it only grows up to that size and then the other items in its track picks up the remaining size. Item 16 opts out from resizing by setting align-self: end. Item 18 has bottom: auto so it’s centered in its allotted space instead of growing. Item 20 has margin-top: auto so it’s aligned to the end while its top-margin grows.

+
+
+ Here’s the corresponding testcase with a masonry inline-axis instead. +
+ +
Visualization of the justify-tracks: stretch example above.
+
+
+

7.3. Individual Track Alignment in the Masonry Axis

+

align-tracks / justify-tracks values can be specified per track.

+
+ Here’s an example to illustrate this. Note that the align-tracks value intentionally has one value less than the number of tracks to illustrate that the remaining track(s) use the last value (i.e. the right-most track also uses space-evenly). (baseline values are also supported but excluded in this test, see § 7.4 Baseline Alignment in the Masonry Axis for a description how that works with examples.) +
+ +
Rendering of the align-tracks alignment example above.
+
+
+

7.4. 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 supported also in the masonry axis, on the first and last item in each track (but not on items "in the middle" of the track). Only tracks with the align-tracks / justify-tracks values start, end or stretch, support baseline alignment. There are four different sets of baseline-sharing groups:

+
    +
  1. the first item in each start track + the first item in each stretch track +
  2. the last item in each start track +
  3. the first item in each end track +
  4. the last item in each end track + the last item in each stretch track +
+

Each of those sets can have a first baseline set and a last baseline set, resulting in eight unique baseline sets in the masonry axis.

+

specify how the grid container’s first(last) baseline in the masonry axis is determined

+
+ Here’s an example illustrating all eight possibilities. +(The example uses two separate grid containers to illustrate the first ("F") and last ("L") baseline sets to avoid cluttering the illustration, but it is possible to use all eight sets in the same container.) The aligned baselines are indicated with red color. Note that the tracks that are attached to the end side of the masonry box adjust the padding (or margin in the case of align-self) on the end side, whereas tracks attached to the start side adjust the start padding/margin. (only align-content is used in this example, which adjusts the padding, since it’s easier to see the baseline adjustment. align-self can also be used, or a mix of the two, as usual.) +
+ +
The rendering of the example above.
+
+
+

this needs more details about edge cases, caveat about misalignment in stretch, etc

+

Authors are advised to be careful with using alignment values other than start when some items span more than one track, because it’s easy to cause items to unintentionally overlap in this case.

+

can we make stretch alignment (at least) smarter so that we avoid overlapping spanning items in a few more cases that would be useful to authors?

+

8. Fragmentation

+

8.1. 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.
+
+
+

8.2. 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 which grid-axis track each item is placed into occurs as a separate step upfront 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.
+
+
+

9. Subgrids

+

Masonry layout is supported also in subgrids (e.g. grid: subgrid / masonry). However, only a parent grid axis can be subgridded in the normal sense. A subgrid axis with a parent masonry axis will behave as masonry, unless the subgrid’s other axis is also masonry in which case it behaves as none (a grid container can only have one masonry axis). auto-placed subgrids don’t inherit any line names from their parent grid because that would make the placement of the subgrid’s grid items dependent on layout results, but subgrid’s tracks are aligned to the parent’s tracks as usual. Here’s a subgrid example:

+
+ +
<style>
+.grid {
+  display: inline-grid;
+  grid: auto auto 100px / masonry;
+  align-content: center;
+  height: 300px;
+  border: 1px solid;
+}
+
+.grid > * {
+  margin: 5px;
+  background: silver;
+}
+.grid > :nth-child(2n) {
+  background: pink;
+}
+
+.grid subgrid {
+  display: grid;
+  grid: subgrid / subgrid;
+  grid-row: 2 / span 2;
+  grid-gap: 30px;
+}
+.grid subgrid > * { background: cyan; }
+</style>
+
+
<div class="grid">
+  <item>1</item>
+  <item>2</item>
+  <item>3</item>
+  <subgrid>
+    <item style="height:100px">subgrid.1</item>
+    <item>sub.2</item>
+    <item>s.3</item>
+  </subgrid>
+  <item>4</item>
+  <item>5</item>
+  <item style="width: 80px">6</item>
+  <item>7</item>
+</div>
+
+
+ +
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 placement 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.

+
+

10. Absolute Positioning

+

Grid-aligned absolute-positioned descendants are supported. In the masonry axis all grid positions except line 1 are treated as auto. Line 1 in the masonry axis corresponds to the start of the masonry box (the content-box start edge usually) and auto uses the grid container padding edge as usual. The containing block is the extent of the tracks the item spans in the grid axis and the position of line 1 and the padding-box edge in the masonry axis.

+

It might be useful to define a static position in the masonry axis though, given that we only have a one line in that axis to align to. Maybe it could defined as the max (or min?) current running position of the grid-axis tracks at that point?

+

It would also be useful to be able to align the masonry box end edge somehow, but for that we need a way to address the end line in an implicit grid, or could we just use any non-auto line number other than 1 to indicate the end line given that we don’t really have any lines in this axis other than line 1?

+

11. 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. That said, align-tracks: stretch specifically adds a cost proportionate to the number of items that are resized. (Note that stretch isn’t the default value for these properties though.) 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.

+

This can be ameliorated by the author by opting out from the stretching on most items though, e.g. specifying align-items:start and then opting in for just a few items with align-self:stretch to let those items fill the masonry axis. Other justify-tracks / align-tracks values such as center, end and '<content-distribution>' (other than stretch) shouldn’t be a problem though since they just reposition the items which is fast. (This performance analysis is from a Gecko perspective, but I suspect there’s some truth to it for other layout engines as well.)

+

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

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

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

+
+
+

Conformance

+

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. + The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” + in the normative parts of this document + are to be interpreted as described in RFC 2119. + However, for readability, + these words do not appear in all uppercase letters in this specification.

+

All of the text of this specification is normative + except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

+

Examples in this specification are introduced with the words “for example” + or are set apart from the normative text with class="example", like this:

+
This is an example of an informative example.
+

Informative notes begin with the word “Note” + and are set apart from the normative text with class="note", like this:

+

Note, this is an informative note.

+
+ +

Index

+

Terms defined by this specification

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Terms defined by reference

+ +

References

+

Normative References

+
+
[CSS-ALIGN-3] +
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. 21 April 2020. WD. URL: https://www.w3.org/TR/css-align-3/ +
[CSS-BREAK-4] +
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 4. 18 December 2018. WD. URL: https://www.w3.org/TR/css-break-4/ +
[CSS-DISPLAY-3] +
Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 19 May 2020. CR. URL: https://www.w3.org/TR/css-display-3/ +
[CSS-GRID-2] +
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS Grid Layout Module Level 2. 18 August 2020. CR. URL: https://www.w3.org/TR/css-grid-2/ +
[CSS-SIZING-3] +
Tab Atkins Jr.; Elika Etemad. CSS Intrinsic & Extrinsic Sizing Module Level 3. 22 May 2019. WD. URL: https://www.w3.org/TR/css-sizing-3/ +
[CSS-VALUES-3] +
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 6 June 2019. CR. URL: https://www.w3.org/TR/css-values-3/ +
[CSS-VALUES-4] +
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 31 January 2019. WD. URL: https://www.w3.org/TR/css-values-4/ +
[CSS2] +
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: https://www.w3.org/TR/CSS2/ +
[RFC2119] +
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119 +
+

Informative References

+
+
[CSS-BOX-4] +
Elika Etemad. CSS Box Model Module Level 4. 21 April 2020. WD. URL: https://www.w3.org/TR/css-box-4/ +
[CSS-WRITING-MODES-3] +
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 10 December 2019. REC. URL: https://www.w3.org/TR/css-writing-modes-3/ +
+

Property Index

+
+ + + + + + + + + +
Name + Value + Initial + Applies to + Inh. + %ages + Anim­ation type + Canonical order + Com­puted value +
align-tracks + [normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>]# + normal + grid containers with masonry layout in their block axis + no + n/a + discrete + per grammar + specified keyword(s) +
grid-template-columns + none | <track-list> | <auto-track-list> | subgrid <line-name-list>? | masonry + none + grid containers + no + refer to corresponding dimension of the content area + see CSS Grid + per grammar + the keyword none or the keyword masonry or a computed track list +
grid-template-rows + none | <track-list> | <auto-track-list> | subgrid <line-name-list>? | masonry + none + grid containers + no + refer to corresponding dimension of the content area + see CSS Grid + per grammar + the keyword none or the keyword masonry or a computed track list +
justify-tracks + [normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ] ]# + normal + grid containers with masonry layout in their inline axis + no + n/a + discrete + per grammar + specified keyword(s) +
masonry-auto-flow + [ pack | next ] || [definite-first | ordered ] + pack + grid containers with masonry layout + no + n/a + discrete + per grammar + specified keyword(s) +
+
+

Issues Index

+
+
specify how the grid container’s first(last) baseline in the masonry axis is determined
+
this needs more details about edge cases, caveat about misalignment in stretch, etc
+
can we make stretch alignment (at least) smarter so that we avoid overlapping spanning items in a few more cases that would be useful to authors?
+
It might be useful to define a static position in the masonry axis though, given that we only have a one line in that axis to align to. Maybe it could defined as the max (or min?) current running position of the grid-axis tracks at that point?
+
It would also be useful to be able to align the masonry box end edge somehow, but for that we need a way to address the end line in an implicit grid, or could we just use any non-auto line number other than 1 to indicate the end line given that we don’t really have any lines in this axis other than line 1?
+
+ + + + + + + + \ No newline at end of file diff --git a/layout/docs/css-grid-3/examples/align-tracks-example-1.html b/layout/docs/css-grid-3/examples/align-tracks-example-1.html new file mode 100644 index 000000000000..647ac7775641 --- /dev/null +++ b/layout/docs/css-grid-3/examples/align-tracks-example-1.html @@ -0,0 +1,105 @@ + + + + + +
align-tracks: normalalign-tracks: space-betweenalign-tracks: end +
+
align-content: normal
+
+ 1 + 2 + 3 +
+
align-content: normal
+
+ 1 + 2 + 3 +
+
align-content: normal
+
+ 1 + 2 + 3 +
+ + +
+
align-content: start
+
+ 1 + 2 + 3 +
+
align-content: start
+
+ 1 + 2 + 3 +
+
align-content: start
+
+ 1 + 2 + 3 +
+ + +
+
align-content: center
+
+ 1 + 2 + 3 +
+
align-content: center
+
+ 1 + 2 + 3 +
+
align-content: center
+
+ 1 + 2 + 3 +
+ + +
+
align-content: end
+
+ 1 + 2 + 3 +
+
align-content: end
+
+ 1 + 2 + 3 +
+
align-content: end
+
+ 1 + 2 + 3 +
+
+ diff --git a/layout/docs/css-grid-3/examples/align-tracks-example-2.html b/layout/docs/css-grid-3/examples/align-tracks-example-2.html new file mode 100644 index 000000000000..57cbab6bf666 --- /dev/null +++ b/layout/docs/css-grid-3/examples/align-tracks-example-2.html @@ -0,0 +1,59 @@ + + + + + +
+ + + + 40px + + + + vertical + + A
B
+ + + + + + + + + + +
diff --git a/layout/docs/css-grid-3/examples/balloon-1.webp b/layout/docs/css-grid-3/examples/balloon-1.webp new file mode 100644 index 000000000000..f9ba48aabe86 Binary files /dev/null and b/layout/docs/css-grid-3/examples/balloon-1.webp differ diff --git a/layout/docs/css-grid-3/examples/balloon-2.webp b/layout/docs/css-grid-3/examples/balloon-2.webp new file mode 100644 index 000000000000..9901395f28c1 Binary files /dev/null and b/layout/docs/css-grid-3/examples/balloon-2.webp differ diff --git a/layout/docs/css-grid-3/examples/fragmentation-block-axis-example.html b/layout/docs/css-grid-3/examples/fragmentation-block-axis-example.html new file mode 100644 index 000000000000..fd9f7b8a253e --- /dev/null +++ b/layout/docs/css-grid-3/examples/fragmentation-block-axis-example.html @@ -0,0 +1,45 @@ + + + + + +
+
+ + +
+
+ + + diff --git a/layout/docs/css-grid-3/examples/fragmentation-inline-axis-example.html b/layout/docs/css-grid-3/examples/fragmentation-inline-axis-example.html new file mode 100644 index 000000000000..2f0240389f9d --- /dev/null +++ b/layout/docs/css-grid-3/examples/fragmentation-inline-axis-example.html @@ -0,0 +1,42 @@ + + + + + +
+
+ +
+
+ + + diff --git a/layout/docs/css-grid-3/examples/graceful-degradation-example.html b/layout/docs/css-grid-3/examples/graceful-degradation-example.html new file mode 100644 index 000000000000..4c198a199924 --- /dev/null +++ b/layout/docs/css-grid-3/examples/graceful-degradation-example.html @@ -0,0 +1,60 @@ + + + + + +
+ + + + 40px + + + + vertical + + A
B
+ + + + + + + + + + +
diff --git a/layout/docs/css-grid-3/examples/grid-intrinsic-sizing-example-1.html b/layout/docs/css-grid-3/examples/grid-intrinsic-sizing-example-1.html new file mode 100644 index 000000000000..38893281f5bd --- /dev/null +++ b/layout/docs/css-grid-3/examples/grid-intrinsic-sizing-example-1.html @@ -0,0 +1,19 @@ + + + +
+ 1 + 2 + 3 + 4 + 5 + 6 +
diff --git a/layout/docs/css-grid-3/examples/justify-tracks-example-1.html b/layout/docs/css-grid-3/examples/justify-tracks-example-1.html new file mode 100644 index 000000000000..f06ef22bbf6b --- /dev/null +++ b/layout/docs/css-grid-3/examples/justify-tracks-example-1.html @@ -0,0 +1,59 @@ + + + + + +
+ + + + 80px + + + + vertical + + A
B
+ + + + + + + + + + +
diff --git a/layout/docs/css-grid-3/examples/masonry-auto-flow-next.html b/layout/docs/css-grid-3/examples/masonry-auto-flow-next.html new file mode 100644 index 000000000000..7d9be4d81841 --- /dev/null +++ b/layout/docs/css-grid-3/examples/masonry-auto-flow-next.html @@ -0,0 +1,35 @@ + + + + + Example of 'masonry-auto-flow: next' masonry layout + + + + + +
+ 1 + 2 + 3 + 4 +
+ + + diff --git a/layout/docs/css-grid-3/examples/masonry-axis-alignment-1.html b/layout/docs/css-grid-3/examples/masonry-axis-alignment-1.html new file mode 100644 index 000000000000..19c238bb86e9 --- /dev/null +++ b/layout/docs/css-grid-3/examples/masonry-axis-alignment-1.html @@ -0,0 +1,77 @@ + + + + + CSS Grid Test: Masonry layout with multiple `align-tracks` values + + + +
align-tracks: start, end, center, stretch, space-between, space-around, space-evenly
+ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 vertical-lr + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 vertical-rl + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + diff --git a/layout/docs/css-grid-3/examples/masonry-axis-baseline-alignment-1.html b/layout/docs/css-grid-3/examples/masonry-axis-baseline-alignment-1.html new file mode 100644 index 000000000000..b42962c8468d --- /dev/null +++ b/layout/docs/css-grid-3/examples/masonry-axis-baseline-alignment-1.html @@ -0,0 +1,92 @@ + + + + +
align-tracks: start, start, stretch, start, start, end, end, stretch, end, end
+ +
+
F
x
+
F
x
+
F
+ +     + +
F
x
+
F
+ +     +     +     +     +     +     +     + +
F
x
+
F
+ +
F
x
+
F
+
F
+
+ +
+ x
L
+ x
L
+
L
+ +     + + x
L
+
L
+ +     +     +     +     +     +     +     + + x
L
+
L
+ + x
L
+
L
+
L
+
+ + diff --git a/layout/docs/css-grid-3/examples/pinterest-with-span.html b/layout/docs/css-grid-3/examples/pinterest-with-span.html new file mode 100644 index 000000000000..a11c4be397cb --- /dev/null +++ b/layout/docs/css-grid-3/examples/pinterest-with-span.html @@ -0,0 +1,47 @@ + + + + + Pinterest-like masonry layout with placed and spanning items + + + + + +
+

Balloons

+ + + + + +
+ + + diff --git a/layout/docs/css-grid-3/examples/rtl-grid-axis.html b/layout/docs/css-grid-3/examples/rtl-grid-axis.html new file mode 100644 index 000000000000..496be36e195b --- /dev/null +++ b/layout/docs/css-grid-3/examples/rtl-grid-axis.html @@ -0,0 +1,35 @@ + + + + + Masonry: example of direction:rtl in the grid-axis + + + + + +
+ 1 + 2 + 3 + 4 +
+ + + diff --git a/layout/docs/css-grid-3/examples/rtl-masonry-axis.html b/layout/docs/css-grid-3/examples/rtl-masonry-axis.html new file mode 100644 index 000000000000..e615f3f17a05 --- /dev/null +++ b/layout/docs/css-grid-3/examples/rtl-masonry-axis.html @@ -0,0 +1,37 @@ + + + + + Masonry: example of direction:rtl in the masonry-axis + + + + + +
+ 1 + 2 + 3 + 4 +
+ + + diff --git a/layout/docs/css-grid-3/examples/subgrid-example-1.html b/layout/docs/css-grid-3/examples/subgrid-example-1.html new file mode 100644 index 000000000000..0e4e90f10a6e --- /dev/null +++ b/layout/docs/css-grid-3/examples/subgrid-example-1.html @@ -0,0 +1,52 @@ + + + + + Testcase for bug + + + +
+ 1 + 2 + 3 + + subgrid.1 + sub.2 + s.3 + + 4 + 5 + 6 + 7 +
+ + + diff --git a/layout/docs/css-grid-3/images/align-tracks-example-1.png b/layout/docs/css-grid-3/images/align-tracks-example-1.png new file mode 100644 index 000000000000..de8d1695b0b4 Binary files /dev/null and b/layout/docs/css-grid-3/images/align-tracks-example-1.png differ diff --git a/layout/docs/css-grid-3/images/align-tracks-example-2.webm b/layout/docs/css-grid-3/images/align-tracks-example-2.webm new file mode 100644 index 000000000000..78c30bc74183 Binary files /dev/null and b/layout/docs/css-grid-3/images/align-tracks-example-2.webm differ diff --git a/layout/docs/css-grid-3/images/example-pinterest-with-span.png b/layout/docs/css-grid-3/images/example-pinterest-with-span.png new file mode 100644 index 000000000000..3c208f713e20 Binary files /dev/null and b/layout/docs/css-grid-3/images/example-pinterest-with-span.png differ diff --git a/layout/docs/css-grid-3/images/fragmentation-block-axis-example.webm b/layout/docs/css-grid-3/images/fragmentation-block-axis-example.webm new file mode 100644 index 000000000000..a50338009870 Binary files /dev/null and b/layout/docs/css-grid-3/images/fragmentation-block-axis-example.webm differ diff --git a/layout/docs/css-grid-3/images/fragmentation-inline-axis-example.png b/layout/docs/css-grid-3/images/fragmentation-inline-axis-example.png new file mode 100644 index 000000000000..7a25e9873d6e Binary files /dev/null and b/layout/docs/css-grid-3/images/fragmentation-inline-axis-example.png differ diff --git a/layout/docs/css-grid-3/images/fragmentation-inline-axis-example.webm b/layout/docs/css-grid-3/images/fragmentation-inline-axis-example.webm new file mode 100644 index 000000000000..7a25e9873d6e Binary files /dev/null and b/layout/docs/css-grid-3/images/fragmentation-inline-axis-example.webm differ diff --git a/layout/docs/css-grid-3/images/graceful-degradation-example.webm b/layout/docs/css-grid-3/images/graceful-degradation-example.webm new file mode 100644 index 000000000000..78c30bc74183 Binary files /dev/null and b/layout/docs/css-grid-3/images/graceful-degradation-example.webm differ diff --git a/layout/docs/css-grid-3/images/grid-auto-flow-example-1.png b/layout/docs/css-grid-3/images/grid-auto-flow-example-1.png new file mode 100644 index 000000000000..c174a33fb4b4 Binary files /dev/null and b/layout/docs/css-grid-3/images/grid-auto-flow-example-1.png differ diff --git a/layout/docs/css-grid-3/images/grid-intrinsic-sizing-example-1.png b/layout/docs/css-grid-3/images/grid-intrinsic-sizing-example-1.png new file mode 100644 index 000000000000..211832a77f52 Binary files /dev/null and b/layout/docs/css-grid-3/images/grid-intrinsic-sizing-example-1.png differ diff --git a/layout/docs/css-grid-3/images/grid-layout.png b/layout/docs/css-grid-3/images/grid-layout.png new file mode 100644 index 000000000000..13a58f0ab9e3 Binary files /dev/null and b/layout/docs/css-grid-3/images/grid-layout.png differ diff --git a/layout/docs/css-grid-3/images/justify-tracks-example-1.webm b/layout/docs/css-grid-3/images/justify-tracks-example-1.webm new file mode 100644 index 000000000000..34ee45d6de2e Binary files /dev/null and b/layout/docs/css-grid-3/images/justify-tracks-example-1.webm differ diff --git a/layout/docs/css-grid-3/images/masonry-axis-alignment-1.png b/layout/docs/css-grid-3/images/masonry-axis-alignment-1.png new file mode 100644 index 000000000000..4a6964f5a5be Binary files /dev/null and b/layout/docs/css-grid-3/images/masonry-axis-alignment-1.png differ diff --git a/layout/docs/css-grid-3/images/masonry-axis-baseline-alignment-1.png b/layout/docs/css-grid-3/images/masonry-axis-baseline-alignment-1.png new file mode 100644 index 000000000000..3fa52311bc12 Binary files /dev/null and b/layout/docs/css-grid-3/images/masonry-axis-baseline-alignment-1.png differ diff --git a/layout/docs/css-grid-3/images/masonry-box.png b/layout/docs/css-grid-3/images/masonry-box.png new file mode 100644 index 000000000000..78087cced32d Binary files /dev/null and b/layout/docs/css-grid-3/images/masonry-box.png differ diff --git a/layout/docs/css-grid-3/images/pinterest.png b/layout/docs/css-grid-3/images/pinterest.png new file mode 100644 index 000000000000..82ff5b6547ed Binary files /dev/null and b/layout/docs/css-grid-3/images/pinterest.png differ diff --git a/layout/docs/css-grid-3/images/rtl-grid-axis.png b/layout/docs/css-grid-3/images/rtl-grid-axis.png new file mode 100644 index 000000000000..ae19112307f2 Binary files /dev/null and b/layout/docs/css-grid-3/images/rtl-grid-axis.png differ diff --git a/layout/docs/css-grid-3/images/rtl-masonry-axis.png b/layout/docs/css-grid-3/images/rtl-masonry-axis.png new file mode 100644 index 000000000000..c677aa442817 Binary files /dev/null and b/layout/docs/css-grid-3/images/rtl-masonry-axis.png differ diff --git a/layout/docs/css-grid-3/images/subgrid-example-1.png b/layout/docs/css-grid-3/images/subgrid-example-1.png new file mode 100644 index 000000000000..fa6a1fd35c37 Binary files /dev/null and b/layout/docs/css-grid-3/images/subgrid-example-1.png differ