Why ‘display: masonry’? CSSWG Meeting 12/4/2024 I will be walking through the key arguments for creating a new masonry display type. #1 Property/value differences Only applicable in Masonry: masonry-slack masonry-auto-flow Intrinsic auto repeaters repeat(auto-fill, auto) Only applicable in Grid: grid-auto-flow Firstly I’d like to touch on the divergences in properties and values between Grid and Masonry. I won’t go through all of these in detail, but as you can note on the slide, there are several properties and values that either only apply to masonry or only apply to grid… —- Note: grid-template-columns: repeat(auto-fill, max-content), because you don't have cross constraints, but need to remain invalid in grid. #1 Property/value differences Behave differently in each, or have different valid values: grid-template-areas grid-template Track sizing values for grid-template-columns and grid-template-rows Grid has four placement properties, masonry only has two Only grid can use all six justify-* and align-* properties. What happens in error cases? …as well as cases where the property or value sets work differently between the two or have different valid values. All of these quirks need to be defined and called out, and require us to determine what happens in error cases if an author makes a mistake? Things will likely parse but not render expected, which could result in author confusion and frustration. Creating a new display type will allow us to more clearly define the unique behaviors of masonry and help to avoid these sorts of unclear error cases for authors masonry-template-tracks defaults to repeat(auto-areas, auto) #2 Better property defaults Another advantage of a separate display type is that we have the freedom to define better property defaults. As illustrated in the two visulas on this slide, with display: masonry, you get a masonry layout even if you don't specify any tracks. This is because we are able to define a better default value for masonry-template-tracks that creates as many auto-sized tracks as will fit the container Because we can’t change the default for tracks in grid, we aren’t able to guarantee the same convenient default behavior. A note on Grid as the default fallback Needing a fallback for Masonry is a temporary problem Grid may be a good fallback in some cases Authors should make the choice of how to fallback consciously to avoid potential surprises with an automatic fallback Speaking of defaults, I wanted to quickly touch on a point that was made around the fact that if masonry lives within the grid spec, it will fallback to grid if Masonry isn’t yet supported. On this topic, I would like to note that the need for a fallback is a temporary problem and we should focus our thinking around what option is the best long term design and solution for developers. When it comes to a fallback, authors should consciously make the decision of what to fallback to, for example, to a masonry pollyfill. Otherwise, they may assume that an automatic fallback will just work, and could be surprised by interop issues. #3 Positioning items is less complex Only allowed in Grid axis Since Grid is multi-dimensional, authors must carefully remember what direction placement is allowed If authors get it wrong with Grid, it will parse but not work With display: masonry, masonry-track-* applies to the Grid axis alone, which makes switching the Masonry direction seamless A third advantage to display:masonry is that positioning items within a masonry container becomes less complex than within the grid spec. In masonry, positioning of items is only allowed to occur in the grid axis. Grid is 2-dimensional in nature, and allows authors to place items in both directions. As a result, if Masonry lives within the grid spec, authors must carefully remember what direction placement happens in, and will likely find it confusing when they get this wrong because error cases will parse, but not have the effect the author intended. With display masonry, on the other hand, the masonry-track properties only apply to the grid axis, avoiding author confusion, and making switching masonry directions seamless. #3 Positioning items is less complex As illustrated in this example, if we place items in a masonry container using display grid, and then change the direction of the masonry axis, this will require the author to provide new item positions in the opposite direction. This extra overhead is not required when using display:masonry #4 Shorthands are more useful Grid shorthand is complex given its 2 dimensional nature, and it is not widely used by authors With display: masonry the shorthand syntax is simpler, and thus, more likely to be utilized by authors .masonry { display: grid; grid: repeat(3, 1fr) / masonry; } .masonry { display: masonry; masonry: repeat(3, 1fr) row; } Shorthands also become more useful with display masonry. More specifically, the grid shorthand is historically known to be very complex given the 2 dimensional nature of grid, and as such, is not widely used by developers. With masonry, however, your can pack more information together within the shorthand, and authors don’t have to think deeply about the ordering of values to achieve the desired effect. We expect that this will make the Masonry shorthand simpler to use and more useful for authors. #5 Masonry placement != Grid placement Another major difference between Grid and Masonry is placement. If an author places the same items in the same order in a Grid container and a Masonry container, you can end up with items being placed in very different locations. This is due to the fact that placement has a completely different definition in both layout algorithms. Due to the interaction of spanners within a Masonry, Masonry will need to define how dense packing works in a different way than Grid #5 Masonry placement != Grid placement On top of this, because of how spanners interact within Masonry, Masonry must also define how dense packing works differently than Grid. In Grid, dense packing works by finding the earliest gap that will fit the item. In Masonry, in order to avoid performance pitfalls, it has been proposed in the linked Github issue that the gaps that would be considered would be those in a track with the same used size as the current track. This extra constraint being applied to Masonry is illustrated in the graphic on the slide, which adds to further algorithmic diversion that authors need to keep track of. #6 Masonry implies different intrinsic sizing Beyond placement, Masonry also implies different intrinsic sizing than Grid. To resolve intrinsically sized tracks in masonry efficiently, items are grouped by spanning size, and the maximum contribution from each such group must be considered in every possible track position. This means that in an intrinsically sized masonry, you can end up with larger track sizes even if no item that is placed in the track ends up requiring it. This is not the case with Grid. #7 Alignment needs to be defined differently Alignment also needs to be defined differently in the masonry axis. As noted in the visual, spanning items create extra spaces that can be used for alignment. For items 1,2, and 3, alignment would have no impact since there is no extra space, but items 4,5,6 and 7 can take advantage of the extra gaps that the spanning item provides. However, what should happen if you added another center aligning item to the third column? How should space be distributed in this case? These intricacies will need to be further discussed and specified, but because grid conversely defines distinct rows and columns, these open questions only apply to masonry, which ultimately leads to further divergences between the two algorithms. #8 Subgrid needs to be defined differently In Masonry layout, auto-placed subgrids don’t inherit any line names from their parent grid, because that would require the subgrid to have a single definite placement, which is not possible in the Masonry placement algorithm since final placement is determined after track sizing is completed And if that wasn’t enough, subgrid, will also work differently in Masonry than grid. 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. #8 Subgrid needs to be defined differently As Submasonry gets further fleshed out, we expect to find more areas of divergence that will need to be explicitly defined in the spec E.g., how to account for auto-placed items in a Submasonry within a Grid ancestor? Likely we will need to extend the concept of the virtual item groups further than just in Masonry’s track sizing As subgrid is further fleshed out in the spec, we expect further divergences to need to be defined. For example, how should we account for auto placed items in a submasonry that has a grid ancestor? Solving for this problem will likely require us to extend the concept of virtual items that was introduced to achieve the masonry intrinsic sizing optimization, meaning that the creation of masonry virtual items may need to become a normalized part of the spec that only applies to Masonry and not Grid. #9 Reduced spec complexity & improved teachability All of these differences between Grid & Masonry from points 1 to 8 lead to the following if Masonry is incorporated into CSS Grid Level 3: Spec bloat Reduced teachability Developer confusion That is all to say, each of the points leading up to this slide illustrate the wide range of divergences that exist between Grid and Masonry layout. Incorporating Masonry into the Grid spec would add spec bloat to an already overloaded specification, which ultimately requires authors to remember and understand what properties, values and behaviors apply to each, which ultimately will make Masonry difficult to teach and difficult for authors to understand and use. Keeping these separate will reduce this overhead and also allow for more flexibility when future divergences are introduced into the spec Our conclusion: Masonry should be a separate display type And as such, all of these points lead to the ultimate conclusion that masonry should be moved to a separate display type as a better long term solution for authors. Further resources Github ‘display: masonry’ proposal and discussion CSSWG issue #9041 BlinkOn talk discussing support for ‘display: masonry’ Ethan Jimenez “How Should we define CSS Masonry” Rachel Andrew, Ian Kilpatrick, Tab Atkins And that is all that I had - please check out the following links for further information. Thanks for your time!