Grid with unknown number of cells of unknown widths in CSS

Viewed 1366

Suppose we have a responsive grid container with indefinite number of child cells. Cells' widths and heights vary. Using only CSS (probably CSS Grid), how can we create such grid, that number of columns / rows and the width / height of each column / row is determined dynamically based on the container's size (without overflowing it) and cells' sizes in one of the following two ways:

  1. Width / height for each column / row is determined based on the widest / tallest cell in that column / row,
  2. Width / height for all the columns / rows is determined based on the widest / tallest cell in the grid?

When applied to column width, these two cases loosely correspond to, respectively, automatic and fixed layout algorithms for tables. Except we don't know the number of columns and rows; it needs to be somehow determined automatically.

The following examples demonstrate these two cases applied to column width. For each case there are two possible flow directions: row or column. Note that in the examples we had to set the number of columns and their sizes specifically. I would like those to be determined automatically.

Please try to replicate these examples in your answer without setting the exact number of columns, rows and any widths or heights.

* {
  box-sizing: border-box;
}

.container {
  display: grid;
  flex-wrap: wrap;
  grid-template-rows: repeat(3, auto);
  justify-content: space-between;
  border: 3px solid teal;
  font-size: 20px;
}
.flex {
  grid-template-columns: repeat(3, auto);
  width: min-content;
}
.fixed {
  grid-template-columns: repeat(3, 33.33%);
  width: 28em;
}
.column {
  grid-auto-flow: column;
}

.cell {
  padding: 1em;
  background: pink;
  border: 1px dashed teal;
  white-space: nowrap;
}

h3:not(:first-of-type) {
  margin-top: 3em;
}
<h3>Flexible column width. Flow in rows</h3>
<div class="container flex row">
 <div class="cell">One</div>
 <div class="cell">Two</div>
 <div class="cell">Buckle my shoe</div>
 <div class="cell">Three</div>
 <div class="cell">Four</div>
 <div class="cell">Knock at the door</div>
 <div class="cell">Five</div>
 <div class="cell">Six</div>
</div>

<h3>Flexible column width. Flow in columns</h3>
<div class="container flex column">
 <div class="cell">One</div>
 <div class="cell">Two</div>
 <div class="cell">Buckle my shoe</div>
 <div class="cell">Three</div>
 <div class="cell">Four</div>
 <div class="cell">Knock at the door</div>
 <div class="cell">Five</div>
 <div class="cell">Six</div>
</div>

<h3>Fixed column width. Flow in rows</h3>
<div class="container fixed row">
 <div class="cell">One</div>
 <div class="cell">Two</div>
 <div class="cell">Buckle my shoe</div>
 <div class="cell">Three</div>
 <div class="cell">Four</div>
 <div class="cell">Knock at the door</div>
 <div class="cell">Five</div>
 <div class="cell">Six</div>
</div>

<h3>Fixed column width. Flow in columns</h3>
<div class="container fixed column">
 <div class="cell">One</div>
 <div class="cell">Two</div>
 <div class="cell">Buckle my shoe</div>
 <div class="cell">Three</div>
 <div class="cell">Four</div>
 <div class="cell">Knock at the door</div>
 <div class="cell">Five</div>
 <div class="cell">Six</div>
</div>

1 Answers

I had the same problem, using column, and this was fixed by adding grid-template-columns: repeat(auto-fit, minmax(baseValue,maxValue)); to the parent element

Related