Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make grid container fill columns not rows

I want my grid to fill in vertically like this:

1 4 7  2 5 8 3 6 9 ... arbitrary number of additional rows. 

Instead, it fills in horizontally like this:

1 2 3 4 5 6 7 8 9 

I want to specify the number of columns in my grid, not the number of rows.

This is what my div looks like with inline CSS styling:

<div style="display:grid; grid-template-columns:1fr 1fr 1fr;">    <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>

It's important that my grid be 3 columns wide, but I want the items to be populated by column, not by row. Is this possible in CSS Grid? I've read through this https://css-tricks.com/snippets/css/complete-guide-grid/ but didn't see anything about order.

CSS Flexbox has flex-direction, isn't there an attribute like that for CSS Grid?

like image 405
Glen Pierce Avatar asked May 21 '17 02:05

Glen Pierce


People also ask

How do you autofit in grid?

The key is to use auto-fill instead of auto-fit . When the repeat() function is set to auto-fit or auto-fill , the grid container creates as many grid tracks (columns/rows) as possible without overflowing the container. Note that as the grid container is being rendered, the presence of grid items is irrelevant.

What does grid Auto Flow do?

The grid-auto-flow CSS property controls how the auto-placement algorithm works, specifying exactly how auto-placed items get flowed into the grid.


Video Answer


2 Answers

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

like image 165
Michael Benjamin Avatar answered Sep 30 '22 16:09

Michael Benjamin


Another option is to drop CSS Grid and use CSS Columns, which does exactly what you ask and also have much better browser support.

.csscolumn {    -webkit-column-count: 3;  /* Chrome, Safari, Opera */    -moz-column-count: 3;     /* Firefox */    column-count: 3;  }    /* styling for this demo */  .csscolumn {    width: 50%;  }  .csscolumn + .csscolumn {    margin-top: 10px;    padding-top: 10px;    border-top: 1px solid;  }
<div class="csscolumn">    <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>    <div class="csscolumn">    <div>1</div>    <div>2</div>    <div>3</div>    <div>4</div>    <div>5</div>  </div>    <div class="csscolumn">    <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>10</div>  </div>
like image 41
Asons Avatar answered Sep 30 '22 15:09

Asons