Closed jensimmons closed 1 month ago
I used the Masonry jQuery plugin back in the day for a few things, and I've missed it in a number of places since then. I've even built similar systems with JavaScript and CSS Grid, by defining absurd numbers of rows and dynamically calculating a row span for each item, which allowed me to do some of the neat column-spanning and column-picking seen in Jen's examples.
Extending CSS Grid with "masonry rows" seems like a great idea to me, and the right place for it. That would allow us web devs to grow our existing knowledge as the possibilities grow, and to leverage our existing code and understanding as we do so. We've already seen how flexbox and grid are (wrongly) viewed as competitors; adding yet another fundamental layout would just confuse things more. Empowering the layouts we have is the better option.
I agree that masonry is a type of grid and should be implemented as such. I also used the Jquery plugin back in the day, it would be nice to have this functionality in CSS. I've had to implement a sub-optimal version of this as a result.
I think masonry (or whatever it ends up being called) should be a part of CSS Grid, for a few reasons:
~
Side note: One thing we've discovered over the past 10 years has been the importance of being able to intuitively predict how a masonry grid will re-flow when content is added to or rearranged within it. Let’s say you have a Pinterest-style image grid, and you load in an additional 50 items... if all the existing items suddenly jump around and switch columns etc that gets really disorienting for users. Same goes for making an element span multiple columns... you don’t expect that to suddenly rearrange the entire grid, simply the content below that element (like upside-down Tetris). I’m hopeful CSS grid’s ability to specify a column position will help with this, which is another reason to build on the existing Grid spec.
Key thoughts on this proposal:
1) Should this be part of CSS grid? I agree it should, if (and only if) it can be implemented orthogonally to other grid features. By that, I mean it should do something sensible when combined with every other grid option. If that's not likely to happen (consistently, in each browser), I don't think it should. This really needs to have a suite of conformance test pages fairly early on.
1) It's unclear whether grid-template-columns
would be equally supported - IMO not doing so would be a serious mistake, because everything else in grid works equally on either axis
2) I've seen various requirements RE the slot fill order for masonry layout. grid-auto-flow
doesn't appear to work with masonry layout in safari tech preview.
2) Other grid features: Spanning and track sizing are very common requirements. I struggle to think of a sensible way to use explicit placement with masonry, although I'm sure someone will. Subgrid might be useful with spanning, although it feels very complex and I'd expect implementations to vary sufficiently that I probably couldn't rely on it for authoring.
2) Spanning columns is of virtually no use (I'll still end up having to use JS or something anyways) without a way to control how the extra whitespace this creates is positioned (eg I set justify-content: space-between; align-content: space-between
, but the extra whitespace all ends up below the image - see ).
Minor nits on the demo at https://webkit.org/demos/grid3//photos/ :
img
tags lack an aspect-ratio<code>
block live-editable would be very nice.I've worked with CSS for what, twenty years, and been a web dev since 1995. Yes, we want this. Masonry layout would solve so many problems for my art and photography websites. Even today I had to fire up Gimp to resize photos for different aspect ratios.
I see Jen's promotion of this in my Fedi feed, and I just tried some of her demos, especially the photos demo. I guess my concern is not particularly with 'Masonry' but with the 'modern' trend toward web pages designed for huge screens. I have two main routes (limited by lousy vision). The smallest iPhone, where after a confusing delay the photos demo reverted to a vertical scroll of single images (that didn't seem connected to the grid images I'd been able to see). And a 1920x1080 Linux view where what's left of the browser window after headers and toolbars took about a minute to fill up with one-third of the full example - many images a half-inch across. Scrolling to the other 2/3 happened painfully slowly, with the image grid filling in random order.
Maybe I missed it, but is there any 'Responsive' technology being discussed to make these new web features work for people who don't have the huge screen area to take advantage of them? Or for people dependent on Alt text? WAVE shows no Alt text at all in the demo. And if there was, a grid of 51 images would be a bit much to navigate...
In that vein, WAVE finds no headings! "Headings ... provide important document structure, outlines, and navigation functionality to assistive technology users." There really needs to be some rational structure within the page for those of us who can't just glance at the whole wall of images at once!
If someone knows a better place to post this issue, please suggest!
@DanielHeath Just noticed this: There's heaps of CLS on a slow connection because the img tags lack an aspect-ratio
Is that why my view loaded so slowly? Granted I'm at the far end of 30 miles of WISP radio, but my 10 Mb usually loads web pages in milliseconds, not minutes.
Anyone who's been a part of the dev community long enough and who has been talking and listening to designers and developers in the community knows that we do want masonry layout. We may not all be working on "big websites", but we are the ones building the Web.
I cast an additional vote to including masonry as part of the CSS Grid layout system, not a separate display
value, for all the reasons @jensimmons mentioned in the article. All of them.
I have been waiting for this layout for to become possible in CSS for years. And it only makes sense that we get enough control over it like we would with other layouts. I believe one of the reasons CSS Columns are not as widely used as one would hope is because they are limited and not flexible. We do want control over column widths. And it only makes sense that Grid Level 3 be able to leverage all the capabilities of Grid Level 1 and Level 2.
Thank you Jen and the Webkit team for pushing to make this feature actually usable.
UPDATE: I've read Rachel Andrew's post which explains the alternative proposal for Masonry. I think this post was a much-needed clarification.
Seeing that both proposals would give us the flexibility to design and implement the layouts in Jen's post, I no longer have a strong preference as to which property or spec Masonry goes into. As a developer, I want the flexibility to build creatively. Whichever way we get to do that will be welcome. I appreciate everyone involved in this discussion and who is working to push this feature forward.
Masonry, however implemented, should exist. Photo albums would be a use case I would put this too. Non-symetric would be nice to have because of a mix of aspect ratio.
We recently implemented a masonry grid as part of our website's dashboard, which held a list of infinite-scrolling cards, and we opted to use CSS Grid for it because we wanted control over the columns (using grid-template-columns: repeat(auto-fill, ...)
) like you mentioned. For the rows, for now, we used a bit of JS to give them all a grid-row: span ...
based on each childs height. It's definitely something I'd love to have to be able to progressively enhance this behaviour and remove the need for JS.
In general, it would also be much easier to progressively enhance too in grid. Just add a grid-template-rows: masonry
, if it's not supported, no problem, we get the default grid row generation with cards stretching to fit, which is what I would want as the fallback. Whereas with display: masonry
, that would most likely require an @supports
and/or duping layout rules.
While I already agree with everything mentioned, just adding my own thoughts below:
I've recently shipped a project that could have made great use of masonry layout for a "mega menu". We ended up using standard multicol to get a similar behaviour, but each group has to be manually placed to optimise how much space they take (some have 2 sub-items, other have 8), so it ends up being tedious to place all the pieces. Masonry would make that very easy and solve common layout problems on many projects.
As far as the display
debate, I'd be in favour of keeping everything as grid
. This allows me to remember a single set of properties that work consistently, simply expanding what I know instead of learning new rules, and to easily switch between the behaviours should I need to revert — or more likely, progressively enhance an existing grid.
Regarding the naming, the obvious alternative is columnar
but holy heck would that be confusing: grid-template-rows: columnar
(and if you read further ahead in my comment, would grid-template-columns
also be columnar
…?). I like the off
idea, short and sweet, though I could also see something like:
stagger
, maybe there's a better, similar term?loose
, authors can have trouble with this word vs lose
and it might induce typos… alt: free
?unbound
, as in, not bound to any track (which feels only half-true), alt: detach
/detached
?float
, okay now this is worse… but the "floaty" idea seems right, or like how oil and water have different buoyancy values, they "float" at different levels… though this is also a metaphor, and not a better one that masonryauto
but like none
that is already a valid value)Finally to piggyback on @DanielHeath's comments:
It's unclear whether
grid-template-columns
would be equally supported - IMO not doing so would be a serious mistake, because everything else in grid works equally on either axis
I am wondering about this too. While I wouldn't need it as much, I'd definitely like that flexibility.
And a nitpick of my own:
There's heaps of CLS on a slow connection because the
img
tags lack an aspect-ratio
Not only the lack of width/height (which, ironically, I now consistently do because of Jen's push on that some years ago 😄) but also the 1MB+ PNGs in the article can easily be optimised.
TL;DR: Overall, feeling very positive about all of this!
Should “masonry”/“waterfall” be part of CSS Grid?
As part of CSS yes, but I am more agnostic about whether it should be part of grid vs. a different display mode.
It seems to me the main pro for being part of grid would be that the fallback behavior would be more reasonable.
Are there things you want to do that you can’t do with this model?
The article only discusses (and shows demos of) a column-based / vertical orientation. However, the feature should also support row-based / horizontal orientation for a use case like the Flickr gallery layout:
Even if not supported initially, the syntax should be designed with this future possibility in mind, so
display: masonry-columns
(or display: masonry; masonry-direction: columns
) as opposed to simply display: masonry
. The grid-template-rows: off
would also be sufficient.
EDIT
It was pointed out by @rileybathurst in a comment below that the demo includes two Horizontal options: Horizontal Masonry and Horizontal Flexbox.
However there are nuances to the Flickr version that differ from both of these:
The big difference with the Flickr masonry is that the heights of the rows are dynamic based on the aspect ratios of the bricks in each row. The CSS masonry should also support this option to have dynamic row height (in the case of Flickr) or dynamic column width (in the case of the column-based support described in the blog post) based on the aspect ratios of the contents, so that the ends of the rows/columns are flush with the right/bottom sides of the container, respectively, and the clipping of brick contents is avoided.
I think keeping everything part of grid would be simplest in terms of use with other properties.
Hi 👋 Thanks for the opportunity to share some thoughts - I really liked the article and it comes at a fantastic time as we are doing redesigns of our website. This has been inspirational!
Should “masonry”/“waterfall” be part of CSS Grid?
Yes.
Do you want the capabilities to define a columnar grid with CSS Grid — to use subgrid, spanning, explicit placement, and all the many options for track sizing? Or do you only want the ability to define a classic masonry layout with equal-sized columns?
Variable column sizes would be preferable. These allow for wider range of design options, and I would expect it to not be an uncommon design pattern. The use of subgrid would also be a fantastic capability that I would prefer to see included.
Will you use this? What might you create with it?
We offer users a way to curate (research) works and are looking to provide them with a visually appealing, dynamic, and scalable way to present the curated content. We want to provide them with an option to present their curated works in magazine/print quality layouts, without having to put in much work to do so. The columnar grid would be perfect for this.
Are there things you want to do that you can’t do with this model?
I also wondered about horizontal options, similar to a previous comment raised. I can imagine this also to be an interesting design element if at all possible.
I have not previously contributed to a W3C discussion, so if I missed anything in how to contribute, I am happy to expand further upon request 😊
I prefer this being part of CSS Grid too.
If all the columns are intended to be the same width, it makes this feature feel very similar to the columns
behaviour—one container separated into multiple columns—albeit with children flowing across the columns rather than down them. In fact, it feels somewhat related to the column-fill: balance
property, since it's similarly attempting to pack each column evenly.
If this was to be implemented as a new display style where all the columns were the same width, it should also support the use of the order
property, which provides a lot more flexibility in responsive layouts to get elements balanced nicely.
In any case, if it doesn't end up being implemented as part of Grid, you can expect that authors will often embed grids inside each element to align captions, etc., which seems inherently more work for the UA to handle than a single shared base grid accessed through subgrid.
Some usage scenarios that would benefit me:
Hi! Author of the Masonry JS library here 👋 . I am stoked to see Jen and the WebKit team prioritize making Masonry a first-class citizen in the browser. My heart-felt gratitude ❤️
In my experience, the vast majority of users want uniform column width. CSS grids provide so much power over layout with track sizing. I think that amount of customization over the tracks is an unwanted feature when working with masonry layouts. Typically with a masonry layout, you want the item to have the same size regardless of its position in the grid. So, if you want to be practical, go with display: masonry
, this will satisfy 95% of masonry layout usage.
Having said that, grid-template-rows: masonry
maps to my mental model of how Masonry works, now that CSS grid is an established convention. Personally, I'd like to see "masonry" used as the value name, as it's the convention with 14 years of history. I could also go with grid-template-rows: collapse
, as it describes the behavior better.
Here are some issues that I know will come up. I don't think they need to be solved in this spec/implementation. But they are worth thinking about during this concepting phase.
Day 2 issue for implementing a Masonry layout is dealing with shifting layout caused by loading images. With a masonry layout, the problem is exacerbated as taller cell element causes subsequent cells elements to move to a different column. The issue is best address by setting aspect-ratio
or better yet width
and height
attributes on the <img>
. I'd say it's outside the scope of this proposal to solve for unloaded images in the spec. But, the issue should be addressed in documentation.
@chrisarmstrong mentions above:
One thing we've discovered over the past 10 years has been the importance of being able to intuitively predict how a masonry grid will re-flow when content is added to or rearranged within it.
The classic Masonry layout will shift a newly expanded cell element to the next possible position
https://github.com/w3c/csswg-drafts/assets/85566/ce4a8746-d2a1-4fc9-8e96-f069e50870c2
But users just want the item to open up where they clicked it. I actually had to build a separate layout library, Packery, with a bin packing algorithm to solve for it
https://github.com/w3c/csswg-drafts/assets/85566/4bea6f9f-abff-480d-ad50-195c0bfcb09f
Maybe something like grid-row: maintain
could address this
A good amount of people requested that Masonry have more leeway in its layout algorithm so that horizontal order could be maintained. I eventually added a horizontalOrder
option to Masonry.
Thrilled to see this work. I'll be following this thread merrily.
Yes. Seems like the logical progression of CSS grid. Something that shouldn't be done with JavaScript anymore.
Hi all, while reading the article, I thought about the possibility of having the masonry as a new display
value that can sufficiently interoperate with grid properties, like the flex currently does (e.g. gap
, justify-*
/ align-*
).
This would perhaps ease the mental model for developers and designers, and perhaps simplify the browser implementations, since it will not automatically (and possibly incorrectly) force every grid feature to work with the proposed masonry mode. Instead, the masonry could grow its own vocabulary free of other grid features.
But on the other side, the new display type would just work™ with the most relevant parts of the grid layout (e.g. fine control over columns, gap).
I personally have no strong preference/opinions on either way. Masonry in any form would be a leap forward.
Also, I think the spec should warn us of possible accessibility pitfalls, like:
Maybe I missed it, but is there any 'Responsive' technology being discussed to make these new web features work for people who don't have the huge screen area to take advantage of them? Or for people dependent on Alt text? WAVE shows no Alt text at all in the demo. And if there was, a grid of 51 images would be a bit much to navigate...
In that vein, WAVE finds no headings! "Headings ... provide important document structure, outlines, and navigation functionality to assistive technology users." There really needs to be some rational structure within the page for those of us who can't just glance at the whole wall of images at once!
Thanks! 💛
p.s. Just found a much better explanation to the idea of "segregation with some interoperability" here (from @rachelandrew): https://github.com/w3c/csswg-drafts/issues/9733#issuecomment-2070382976
I recently came across a use-case at work where we want a 2-column layout on desktop, and a single column on mobile. But we want the top item of the right column to be "in the middle" of the single column, and the bottom item of the right column to be at the bottom of the single column like so:
Currently as far as I know there is no way to achieve this in CSS, but with masonry grid it is quite simple to achieve, as shown in this codepen:
https://codepen.io/dougalg/pen/GRLPZea
The benefits of grid here are ability to pull items naturally into different columns following the standard grid syntax, and doing so allows to maintain tab order easily to achieve the desired flow both on mobile and desktop.
Lots of devs seem to find CSS Grid difficult to understand and use. They'd love a super easy way to do Masonry, like this:
main {
display: masonry;
columns: 28ch;
}
But this other way, with all the brackets and stuff, is almost as scary as CSS Grid syntax itself, so I wouldn't go for it:
main {
display: masonry;
masonry-columns: repeat(5, minmax(28ch, 1fr));
/* where only one repeating width is allowed */
}
However we will eventually need those extra syntax for more controls, so...
For the reasons Jen mentioned, I'm all for adding masonry to CSS Grid layout.
@desandro That's a great point RE horizontal order - eg item 11 in the mega-menu demo being positioned to the right of item 12 is correct, but looks totally wrong (see screenshot).
I think masonry should have its own display
value instead of being integrated in the grid
spec. Reasons:
grid
and a masonry
grid is just as different as grid
and flex
.
flex
rather than grid
because the behavior is more similar to a flexbox (one-dimenson flow).masonry-auto-flow
, justify-tracks
and align-tracks
that were created only for masonry but don't make sense for other grid use cases, which is confusing.grid
and flex
share some properties like gap
, align-items
, justify-content
, etc, grid
and masonry
can share only the properties that make sense for both.Please, mayby create an questionnaire like with nesting, to gather more votes on the matter.
Lots of devs seem to find CSS Grid difficult to understand and use. They'd love a super easy way to do Masonry, like this:
main { display: masonry; columns: 28ch; }
But this other way, with all the brackets and stuff, is almost as scary as CSS Grid syntax itself, so I wouldn't go for it:
main { display: masonry; masonry-columns: repeat(5, minmax(28ch, 1fr)); /* where only one repeating width is allowed */ }
However we will eventually need those extra syntax for more controls, so...
For the reasons Jen mentioned, I'm all for adding masonry to CSS Grid layout.
I believe both could be made to work, eg: masonry-columns: 28ch
for a simplified/shorthand version, or masonry-columns: repeat(5, minmax(28ch, 1fr));
if someone wants to be more specific.
I think it should be masonry-columns
instead of just columns
to disambiguate it from the existing columns
I know there was no mention of column masonry layouts, I'm just wondering "why not". I'm all for display: grid
being extended, it's also quite logical in my view. I think the proposed syntax is a logical syntax, you're effectively independently defining a masonry layout in either direction. One difficulty for me would be, how should the following behave?
display: grid;
grid-template-rows: masonry;
grid-template-columns: masonry;
This could be a messy layout as follows:
Or should this be an error condition? If this shouldn't be allowed, it would be a slight problem for me, because it seems to break the line independence of css. Now by adding line 3, you've effectively broken the way line 2 should work. So this case would need to lead to a reasonable layout.
But then my question would be, is this still a grid?
Also, how do I specify the layout direction, because this would also be a valid way to lay out the exact same boxes:
Then we have problems of "how we should align them" or how they should be reflowed to fill the available space. But these are all initial issues that I'm running into when imagining this.
Please make masonry
part of grid. It's already implemented on Firefox, but disabled. Once enabled, it was so easy to build a fluid grid.
The one dependency I would tack on to this is to have browsers respect the Grid/Flex order as the reading order for screen readers and keyboards. If we start rearranging things visually using masonry grids, we want to make sure keyboard uses can still understand how to navigate it.
Items that can span columns and the use of subgrid are incredibly compelling reasons to make the masonry layout (or columnar grids, my preferred name) part of CSS Grid. I recently created a layout for a local newspaper's homepage, but found myself making compromises that I wouldn't've needed to make were masonry a part of the CSS Grid spec (and widely available). Those compromises would have to remain in place forever if CSS masonry doesn't support column spanning or non-symmetrical column sizes.
This is on the front page of Hacker News today, with over 200 comments and counting: https://news.ycombinator.com/item?id=40130148
Should “masonry”/“waterfall” be part of CSS Grid? Yes, it should. It's quite a common layout used for various image galleries.
Do you want the capabilities to define a columnar grid with CSS Grid — to use subgrid, spanning and all the many options for track sizing? Or do you only want the ability to define a classic masonry layout with equal-sized columns? Would love to see a mosaic-like layout implementation similar to Flickr, Google Images, Shutterstock, Adobe Stock, iStock, etc.
First and foremost, I must say it is incredible the work being done here, and I am happy to know this conversation is happening.
I am very passionate about CSS in general and I must say that Grid is not being used as much as I would like to see it being used especially when building layouts.
For context, my name is Astrit, and I work as a front-end developer at SEB. We are creating a design system called Green
and I want to share an example of how we leverage CSS Grid for enhanced layouts and discuss the benefits of implementing a masonry layout.
Within our development process, we use Lit to construct our web components. One of the key layout components is Grid, which uses attributes like columns, gaps, padding, and many more that I will not go through here. This Grid layout operates seamlessly and offers exceptional functionality across all our platforms.
Here is an example how we use it:
<gds-grid
columns="l:8 m:4 s:2"
gap="l:xl m:l s:xs"
row-gap="l:xl m:l s:xs"
padding="l:2xl m:l s:xs"
>
...
</gds-grid>
Might not be the best way to use attributes but still working on it!
Thus far, the results have met our expectations, providing us with highly responsive layouts utilising 'grid-template-columns' with 'repeat' and 'min-max' functions.
Here is an example how that looks like
@layer grid {
/* When using columns prop */
:host {
--_c: var(--gds-sys-grid-columns-12);
--_grid-col: repeat(var(--_c), 1fr);
--_grid-col-start: 1;
--_grid-col-end: -1;
--_gap-column: 0;
--_gap-row: 0;
display: grid;
width: 100%;
grid-template-columns: var(--_grid-col);
grid-column-gap: var(--_gap-column);
grid-row-gap: var(--_gap-row);
padding: var(--_grid-padding);
text-wrap: balance;
}
/*
Auto columns enables us to have columns that respond to content when we want automated columns based on a predefined min width
Eliminate the need for breakpoints, or when necessary to combine having some control while giving priority to content
*/
:host([auto-columns]) {
--_col-count: var(--_c, 0);
--_gap-count: calc(var(--_col-count) - 1);
--_total-gap-width: calc(var(--_gap-count) * var(--_gap-column, 0px));
--_col-width-max: calc(
(100% - var(--_total-gap-width)) / var(--_col-count)
);
grid-template-columns: repeat(
auto-fill,
minmax(max(var(--_col-width), var(--_col-width-max)), 1fr)
);
}
}
The auto-columns
attribute, used with CSS grid layout, calculates the maximum column width by subtracting the total gap width from the total available width and dividing by the number of columns. This is represented by the formula MaxColumnWidth = (W - ((C - 1) * G)) / C
, where W
is the total available width, C
is the number of columns, and G
is the width of a single gap. This calculated width is then used to set each column's width, with a minimum width of the auto-columns
value.
Or you can just straight forward use the auto-columns="200"
attribute that will adapt the columns to have min width of 200px across the board or any value for that matter!
And this way we have managed to cover all the use cases we had except one, which is having a masonry
layout, we already span in between columns and rows how ever if we had something like grid-template-rows: off;
or grid-template-rows: masonry;
it would be super helpful to cover these types of layouts and with that pretty much is limitless and very efficient at the same time.
I am not sure how the logic would follow if you have different language direction and if this logic should be similar for columns
and rows
but as of now any progress on this direction would be more than welcomed.
And for the end I must say these types of things are a big factor of having a much more efficient, maintainable and smaller codebase. And on top of that less libraries and dependencies to do just those calculations.
✌️
Please, mayby create an questionnaire like with nesting, to gather more votes on the matter.
In this case we wanted more qualitative feedback. If we get to a point where it's just preferences on syntax, we could do a poll; but here we want developers to tell us about use cases and explain or show how they would use the feature. One of the core points of contention is whether or not various aspects of the proposal are necessary complications. Therefore comments like https://github.com/w3c/csswg-drafts/issues/10233#issuecomment-2071279204 and https://github.com/w3c/csswg-drafts/issues/10233#issuecomment-2067472993 are particularly helpful.
I think this is necessary and should absolutely be added to CSS Grid where it feels intuitive to me and is okay if some properties have no effect.
A few times a year, I need to create a masonry grid, check to see if it's possible yet without JavaScript, and eventually give up on it or fake it in a hacky way. Everything described in the blog post, including the ability to do multiple-column designs and mixed-size columns thanks to grid, sound phenomenal.
Thank you for this work and hope to see it in major browsers very soon. I definitely see masonry layouts all over the place and would love to implement more of my own if it were easier like this.
A new display type with shared properties seems the faster and cleaner compromise.
All listed capabilities are gladly wanted. (And hungrily awaited for.)
Yes I (we?) will use it in a lot of layouts with different sized content.
I cooked up a masonry layout component recently and have implemented a few ideas so far:
Like anyone implementing masonry layouts, I encountered the problems of resizing and image loading. However as I have added customizable theming, I have encountered the need to repaint the layout on a new font load. If masonry becomes a part of CSS these issues would be managed by the browser.
@kylehotchkiss Do you have an example of a 3D masonry layout? I'm not sure how that would work or look in practice, but I imagine such improvements could be made to grid at the same time. 🙂
As I see it, that's the beauty of masonry being part of grid. Grid and masonry can grow together, so when grid gets new capabilities, so does masonry, and vice versa.
This would also seem to imply easier maintenance and likely fewer new supporting properties needed in the future.
yes, super exciting!
I imagine dashboard layouts in respect to the level of detail of the chart figures
I wonder how the proximity between elements could maybe improved now or later in regard to the original order of nodes (e.g images) in the markup.
grid-template-rows
, also because I can imagine how this alternatively can apply to grid-template-columns
as well to shift the layout direction.grid-template-rows: collapse
Thinking further, grid-template-rows: masonry(0)
could make it a CSS function, which uses the closest (zero) gap, while grid-template-rows: masonry(1)
would always stack the next row next to former without any interference. Fractions between would work like a threshold of how big a relative gap has to be to make the next image populate the slot. In this example picture a threshold of ~0.2 would make image 6 and 7 change places (and sort of maintain a slightly better order in the sense of the given left to right flow). A threshold of ~0.5 would swap image 6 and 8 and keep 7 in place. Obviously this is just a draft here, experiments would need to validate how well this really works out. I share an idea here, which is still sketchy.
I image such kind of control would also help further advance the newspaper examples.
A potential UX problem with masonry is, when content blocks don't stack up well or scrolling content becomes very long. The content block fitting keeps working technically speaking, but the relation to the actual order the html nodes had in markup gets more and more shuffled. This can make the user need to scroll back when looking through all the content in detail to not miss out on one.
I wonder how grids in general could offer a way to split content into chunks, which could be like pages or just sections in an infinite page, but making sure the layout fitting algorithm starts fresh at a certain index. The threshold function mentioned above, could apply a threshold of 1 on a certain nth-child. E.g.
main {
grid-template-rows:masonry(0)
}
main:nth-child(100n) {
grid-template-rows:masonry(1)
}
I would love to write a longer post about this in the future, but I’ll need more time to experiment with the existing masonry prototype implementations, and think about it more.
Based on my preliminary explorations and experiments:
That’s all from me for now — I have many other thoughts, but will need to read all the comments here, and experiment more before I could properly articulate them (and show examples).
Disclaimer: I read the webkit blog post. I'm coming in with a clean set of eyes, but limited expertise in this specific proposal. My background is developing full stack applications (some major, like Open edX, and many little ones), as well as a lot of teaching experience, again, full stack, spanning elementary schools through corporate PD through MIT EECS students. Take this as a 1000-foot-view.
Feedback: I like the concept, but I don't like the proposal as presented here or where the discussion is headed (keeping in mind there are other proposals as well, and a blog post is an imperfect presentation).
I think the key issues are:
This discussion feels like it is far too far on the complexity / pixel-perfection / everything-is-a-div side. As with many of these discussions, it's dominated by front-end developers who are comfortable with language like main:nth-child(100n) { grid-template-rows:masonry(1)}
, let alone --_total-gap-width: calc(var(--_gap-count) * var(--_gap-column, 0px));
. That's a very small portion of people who would be using this.
It's also -- to be frank -- not very important. Big web sites will look a little bit prettier, which will make web devs happy, but I don't think the world improved when it went from Hacker News or Craigslist-style layouts. People are famously okay with simple layouts. Having a nicer one gives a competitive edge, but if everyone has a nicer one, the competitive edge goes away, and we're just treading water. Making ugly layouts easy and nice layouts hard -- which is what happens when HTML / CSS become more complex -- just gives an edge to big corporations who can afford big front-end teams. Keeping things simple has a major effort on democratizing the open web.
What I'd love to see here is HTML and CSS which is simple enough that I mere mortals can read and write layouts without digging through reams of documentation.
I think the trick would be to do user studies with e.g. high school students. Can this proposal (like HTML 2.0) be taught and interesting in a short session? If so, bring it in. Until it's that simple, please leave it out.
I suspect where a proposal might land might be:
<gallery><img><img><img></gallery>
.Publish those, and ask for feedback. See how understandable they are to ordinary individuals -- ideally at the level of high-school students, but at the very least, non-front-end developers. You can even walk into the grumpy sysadmin's office at your own company and see what they think.
FWIW, major use cases I've seen are (1) an image gallery (2) a newspaper-style navigation page, of boxes with text. Those sorts of things might want semantic HTML elements. Using those elements, CSS should be strictly optional.
Another vote for keeping it as part of CSS Grid. Alongside the ability to use subgrid, column spans, and other existing features, as others have noted, making masonry a new feature for Grid allows for easier progressive enhancement and adoption. You could build a regular grid, then enhance to be masonry for those browsers that support it, in a lot of scenarios where this functionality would be used.
I'm also someone who has been hoping for native masonry layouts for some time; many of the reasons given above overlap with my own experience. However, I think it is worth flagging the accessibility concerns that such a fluid layout algorithm can have.
What considerations are being included in the spec for dealing with the disconnect between visual layout order and DOM order? Or for handling focus order correctly? As the nature of masonry is very hands-off from a developer's perspective – we're letting the browser decide placement, after all – it won't be easy (or even impossible) to retroactively patch this behaviour for assistive technologies.
I'm aware that there are discussions elsewhere within the CSS community (and Working Group) around making better, more robust accessibility APIs for functionality like Grid, but masonry seems to come with these concerns baked in and unavoidable, so it would be good to see a concerted effort to ensure that they are covered before masonry sees wide usage or implementation.
@pmitros
the HTML 2.0 days when it could be taught to elementary school students
The great thing about HTML & CSS is that you can still code like it’s 2001 and it’ll all still work... but in reality all the “added complexity” has made it easier to accomplish the things we commonly need to do.
You can still build a house with a hammer, but professionals use more complicated nailguns.
@chrisarmstrong In theory, yes. In practice, no, at least if you want even basic readability.
HTML 2.0 browsers all had their own native styling built-in for things like headers and paragraphs which were different, and designed to look okay on the devices of the day. HTML2 was entirely semantic, and a browser was free to render headers or paragraphs as most appropriate for the context, be that a text-only terminal (remember Lynx?), a graphic browser, Windows 3.1 on a VGA screen, an SGI workstation with a 1600x1200 monitor running Irix, or a screenreader.
Although tables were part of HTML2, they really moved into their "prime" around the time of HTML 3 and 4, where they were widely used to define layout (rather than tabular data). Around the time, there was an expectation that browsers have pixel-perfect layout (which was the era of things like ACID tests). Those were the bad days, but from that point on, a browser could no longer render headings and text as it saw fit and appropriate for the device it was on. The rendering algorithm was specified, and as specified, was designed to look fine on a 640x480 VGA monitor (and even an SVGA monitor).
Consequently, default styling is now locked down to what worked on ancient operating system at low resolutions. Today, modern browsers don't render HTML 2.0 okay. On a 4k monitor, you will have lines in of text in p
tags which run end-to-end on the screen, without reasonable margins. It's unreadable and unusable (at least until you click the little "toggle reader view" icon on Firefox, when it's rendered the way HTML 2.0 was meant to be rendered). Some minimal CSS is needed for even a very baseline level of usability.
(That's not to mention many other issues, such as the move from SGML to XML; modern browsers don't always seem to handle SGML properly)
I'm, of course, not suggesting a return to the HTML2 days. HTML5 was a major clean-up and takes an entirely different philosophy from HTML2. However, I'd like to see newer standards continue with that clean-up and general simplification to where newer standards continue to make things increasingly usable for normal users on a democratic, open web, like we used to have.
Considering there is low browser support currently, we can still use /span
to demark layout strategies
Has some Codepen that on a 12x12 grid you can set row span and col span to get some awesome layout
It seems a some people may have missed the demo in https://webkit.org/demos/grid3/photos/ Photos switch the layout to Horizontal Masonary so make sure to look at all the options this might be what you are thinkink about @keller-mark @chartgerink
Another vote for in grid, the fall back dor a display grid seems like a good place to start
Should “masonry”/“waterfall” be part of CSS Grid?
Absolutely - it's a grid and I want to use all the capabilities of one with the waterfall layout
Do you want the capabilities to define a columnar grid with CSS Grid — to use subgrid, spanning, explicit placement, and all the many options for track sizing? Or do you only want the ability to define a classic masonry layout with equal-sized columns?
PLEASE! I'd love to use the capability and the flexibility that comes with it. Explicit placement is less interesting to me than the other mentioned features
Will you use this? What might you create with it?
Yes, most immediately on a personal profile with a boring static sized grid right now
I think that the masonry/waterfall idea should be part of CSS Grid, but it should also be available in CSS rows not just the column direction.
I attempted to create a masonry like layout for a gallery just the other week. In the end, the solution I ended up with was to use columns: but at the cost of not being able to align the images horizontally.
I'd support adding masonry to the grid specification rather than as an additional display property, the benefits of building on top a well established (and already complicated but feature full) standard makes most sense.
Should “masonry” be part of CSS Grid?
Yes!
Do you want the capabilities to define a single-axis grid with CSS Grid — to use subgrid, spanning, explicit placement, and combining different track sizes?
Yes! I also want the ability to use gap
.
Will you use this at all? What might you do with it?
I've had to implement a masonry-like grid twice in the last year, both times having to research the available options, reading through extensive articles and/or documentation for JavaScript based solutions, but ultimately never landing on a perfect option. The proposed solution solves all of our problems and needs.
Adding it as a display
property would be too limiting.
It’s likely masonry is not the best name for this new value.
I think masonry
makes the most sense given it's usage both in blog posts as well as in the names of JavaScript libraries. It has historical context and weight. Waterfall doesn't convey the same kind of visual imagery as bricks stacked on top of each other.
Yes, I feel "masonry" should be part of grid, but I also agree having it as a display value rather than a template-rows setting makes more sense. IIRC, display takes multiple values. So how about something like this?
display: grid balance;
@desandro Hi Dave! It's good to see you here. I've been a fan of your work for years.
In my experience, the vast majority of users want uniform column width. CSS grids provide so much power over layout with track sizing. I think that amount of customization over the tracks is an unwanted feature when working with masonry layouts. Typically with a masonry layout, you want the item to have the same size regardless of its position in the grid. So, if you want to be practical, go with display: masonry, this will satisfy 95% of masonry layout usage.
By "users" do you mean us devs using the feature? The reason I ask is because the main reason I (as a dev) didn't use the JS plugin back in the days on many websites was because it forced me to set a uniform column size when I wanted more flexibility and freedom to get creative.
I believe that even though the masonry layout is traditionally known for uniform-width columns, non-uniform columns are very appealing. And sticking with uniform widths means that the layout will not be as adaptable to different use cases anymore.
With my CSS Tables editor hat on, I would strongly advise against entirely merging this feature with CSS Grid.
I'll give you two reasons:
As a user, there's a third reason, which is that:
I understand the appeal of "just adding one more feature to Grid" but I don't think this is the right path forward. The difference in performance, ordering of layout steps, and (frankly) desired results make a franken-grid system look unappealing from me. This doesn't mean that masonry has to be limited to a few options only, it can certainly draw inspiration from grid, but I'd prefer this to happen as an inspired copy rather than an intricated inplace edit.
My two cents ;)
We just published an article about Grid Level 3 / Masonry layout on webkit.org, https://webkit.org/blog/15269/help-us-invent-masonry-layouts-for-css-grid-level-3/, and at the end of the article, we asked web designers and developers to weigh in with their thoughts.
We opened this issue to provide a place for people to leave their input after reading the article, to especially answer these questions:
If you are finding this issue through the typical CSSWG channels, please read the article before commenting. It provides 4,000 words of context.