Make grid container fill columns not rows

For a vertically-flowing grid that creates new columns as necessary, and rows are not defined, consider using CSS Multi-Column Layout (example). CSS Grid Layout (at least the current implementation – Level 1) cannot perform this task. Here’s the problem:

In CSS Grid Layout, there is an inverse relationship between the grid-auto-flow and grid-template-rows / grid-template-columns properties.

More specifically, with grid-auto-flow: row (the default setting) and grid-template-columns both defined, grid items flow nicely in a horizontal direction, automatically creating new rows as necessary. This concept is illustrated in the code in the question.

#container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-flow: row;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>

However, with a switch to grid-template-rows, grid items stack in a single column.

#container {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  grid-auto-flow: row;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>

There is no automatic creation of columns with grid-auto-flow: row and grid-template-rows. grid-template-columns must be defined (hence, the inverse relationship with grid-auto-flow).

#container {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-flow: row;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>

The same behavior is true in the reverse scenario.

With grid-auto-flow: column and grid-template-rows both defined, grid items flow nicely in a vertical direction, automatically creating new columns as necessary.

#container {
  display: grid;
  grid-template-rows: 1fr 1fr 1fr;
  grid-auto-flow: column;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>

However, with a switch to grid-template-columns, grid items stack in a single row. (This is the problem most people ask about, including in this question.)

#container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-flow: column;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>

There is no automatic creation of rows. That requires grid-template-rows to be defined. (This is the solution most often provided, but it is usually rejected because the layouts have a variable number of rows.)

#container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-auto-flow: column;
}
<div id="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>

Hence, consider a multi-column layout solution, as suggested above.

Spec reference: 7.7. Automatic Placement: the grid-auto-flow property

Leave a Comment

tech