mgiuffrida
mgiuffrida

Reputation: 3569

CSS grid with auto-sized auto-filled rows

I'd like to create a grid of items that places as many items on each row as can fit. It should:

Effectively, I'm looking for a table with auto-sized columns and an auto number of columns. Flexbox with flex-wrap doesn't work for me, since the columns wouldn't be aligned.

I've tried using grid with auto-fill, but I can't figure out how to ensure each column grows to fit its content. In this example, it only works if I specify a fixed minimum width, e.g.:

grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));

I tried replacing the minmax function with auto, but that results in each column taking up 100% width. Is there another way to achieve what I'm trying to do (without JavaScript)?

div {
  width: 300px;
  border: 1px solid red;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
}
<div>
  <span>word</span>
  <span>word</span>
  <span>longword</span>
  <span>word</span>
  <span>longword</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
</div>

My desired layout would look just like the above, except that any columns containing a "longword" cell would be wide enough to fit that cell (and the number of columns would shrink, if necessary). The end result would be several auto-sized columns, each of which is only as wide as necessary to fit their cells' contents. Basically, an HTML table with an indeterminate number of columns.

Upvotes: 9

Views: 2267

Answers (2)

the Hutt
the Hutt

Reputation: 18408

If you are looking for a masonry layout. The CSS specification for it is still in draft level ref.

However, you can try the specification in Firefox v77 and above. ref
In about:config set the preference layout.css.grid-template-masonry-value.enabled to true and try this demo:

div {
  padding: .5rem;
  width: 300px;
  display: grid;
  gap: 10px;
  grid-template-columns: masonry;
  grid-template-rows: repeat(4, auto);
  border: 1px solid red;
}

div span {
  display: inline-block;
  padding: .5rem;
  border: 1px solid orange;
  border-radius: .5rem;
}
Works only in Firefox v77 and above!
<div>
  <span>word</span>
  <span>word</span>
  <span>longword</span>
  <span>word</span>
  <span>longword</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>long long very long text</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
  <span>word</span>
</div>

For those who do not have Firefox installed, this is how it looks: enter image description here

More demos are available here


For now you'll have to use JavaScript based solutions like:

Upvotes: 1

Knight Industries
Knight Industries

Reputation: 1481

This requirement leads to contradictory scenarios:

Let's say there are 6 cells with the following lengths in that particular order:
11111, 2, 3, 44444, 5, 6

  • 3 columns → width: 7

    |11111|2|3|
    |44444|5|6|
    
  • 2 columns → width: 10

    |11111|2    |
    |3    |44444|
    |5    |6    |
    

⚠️ Reducing the number of columns for smaller screens would result in a wider grid in that case and it wouldn't fit any more.

This is at least one reason why the layout of such a grid could be a complex task, is not supported by CSS and why it is probably not a good idea in general.

Suggestions (CSS-only):

  • Manually define the number of columns for each screen size using media queries
  • or just use flex-wrap and make all cells the same width if they should align.

Upvotes: 3

Related Questions