Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-grid] Request: an easy way to set adjusted-to-fit repeated track sizes #3767

AmeliaBR opened this issue Mar 26, 2019 · 5 comments
css-grid-3 Masonry Layout


Copy link

I'd like an easy & intuitive way to specify the following grid layout pattern:
Set an ideal track size (column width or row height), and then have automatic repeats where the actual track size are adjusted to neatly fit the container, without overflowing or leaving gaps.

In other words, I want column widths that are the same as I'd get for a multi-col layout with:

column-width: <length>;

(I'm using columns in the example for comparison to multi-col, but of course this should also work for auto-repeat rows when the block size of the container is constrained.)

You can get almost all the way there, currently, by saying for your grid container:

grid-template-columns: repeat(auto-fit, minmax(<length>, 1fr));
/* determine the number of columns at the specified min length,
    then stretch all the columns to equal width to fill the available space */

...but that forces the <length> to be treated as a strict minimum track size, causing overflow if the container width is smaller than that. To override the minimum, you either need to wrap the minmax() function in a min() function (when that is eventually supported cross-browser) or use a media query (assuming the container width that triggers overflow can be reliably calculated from the document width).

With a min() constraint added, you're looking at the following CSS:

grid-template-columns: repeat(auto-fit, min(minmax(<length>, 1fr), 100%));

which is:

  • a lot to type compared to the multi-col version.
  • not very intuitive.
  • easy to mess up.

Some potential syntaxes for making that long, complex command simpler:

grid-template-columns: repeat(auto-fit-round, <length>);
grid-template-columns: repeat(auto-fill-round, <length>);
  /* but round as used elsewhere in CSS repeats (round up or down to even integer)
     is different from the multi-col behavior (length is min unless it causes overflow) */

grid-template-columns: repeat(auto-fit-flex, <length>);
grid-template-columns: repeat(auto-fill-flex, <length>);
  /* but would calling it flex make devs think they could control it
      with flex-grow and -shrink properties? Or is it close enough to fr? */

grid-template-columns: repeat(<length>);
  /* short & sweet, but we'd have to decide if this expands 
      to an auto-fit or auto-fill version, re collapsing empty tracks */

PS, If you think there is existing CSS that can handle this more simply, please give it a go:

More examples/discussion courtesy of Amber Weinberg-Jones's tweet:

@AmeliaBR AmeliaBR added the css-grid-3 Masonry Layout label Mar 26, 2019
Copy link

This seems reasonable to me. Randomly thought about auto-adjust to describe this behavior instead of auto-flex but didn't give much thought so just sharing in case others find it useful.

Copy link

It seems simpler (and more flexible) to just add an optional third param as the "ideal length" to repeat(), like so:

repeat(auto-fit/fill, <track-list>, <fixed-breadth>);

<fixed-breadth> would be used for calculating the number of tracks in § <track-list> would be used everywhere else. So your example would be solved by:

repeat(auto-fill, 1fr, 100px);

(Assuming you want an auto track min-sizing function.)

Copy link

Loirooriol commented Mar 27, 2019

Would #2611 solve your usecase? Something like

grid-template-columns: repeat(auto-fit, minmax(1fr, <length>));

and possibly min-width: 0 to the items.

Edit: it seems that the tracks would be limited to <length> but you want to avoid gaps. So it wasn't a good suggestion. But I like Mats' idea.

Copy link
Contributor Author

@Loirooriol It depends on how that is spec'd to behave. The discussion in #2611 doesn't cover how a min value of 1fr would be interpretted in an auto-fit/fill context, and it doesn't look like any matching text ever made it into css-grid-2.

If the auto-fit basis for minmax(1fr, <length>) is treated as the min-content width (the inherent minimum for flex units), squeezing as many columns as possible in, that's not very useful. But if it's treated as "as much space as available, but no more than <length>, then it's useful. It would be different from multi-col, because the specified length would be the maximum instead of the minimum-unless-it-overflows. But it would still address the underlying use case.

Copy link
Contributor Author

AmeliaBR commented Mar 27, 2019

@MatsPalmgren That's definitely one idea: it allows you to still have the full flexibility of the minmax() function and keywords, because you separate out the "how many columns" calculation from the "adjusting the final width" calculation.

To make that separation clearer, maybe the <fixed-breadth> parameter could be included as a function version of auto-fit/-fill:

repeat(auto-fit(<fixed-breadth>), <track-list>);
repeat(auto-fill(<fixed-breadth>), <track-list>);

repeat(auto-fit(100px), 1fr);
   /* fit as many columns as would be possible at 100px width,
  then adjust each to equal width so long as none are less than min-content */
repeat(auto-fit(100px), minmax(0,1fr));
   /* ignore the min-content requirement to make them strictly equal */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
css-grid-3 Masonry Layout
None yet

No branches or pull requests

4 participants