njbair
njbair

Reputation: 1982

How can I set `height: auto` to a CSS grid container while using `grid-auto-flow: column`?

In the below snippet is an example sub-menu layout. I want to evenly distribute the menu items across all three columns, but I want to arrange them vertically.

In the first instance, the items are evenly distributed, but they are arranged horizontally.

In the second instance, I tried switching grid-auto-flow to column to arrange them vertically, but this defaults to a single row no matter what auto-fill/auto-fit values I try to use for grid-template-rows.

In the third instance, I manually set the correct absolute value for grid-template-rows as a proof of concept; but in the real world the number of items (and thus the number of desired rows) will not always be known until render time.

Is there something I can do short of client-side JavaScript to achieve this layout?

.sub-menu {
  margin: 0;
  padding: 2px;
  border: 1px dashed red;
  list-style: none;
  
  /* the actual grid code */
  display: grid;
  grid-gap: 2px;
  grid-template-columns: repeat(3, 1fr);
}

.grid-auto-flow-row { grid-auto-flow: row; }
.grid-auto-flow-column { grid-auto-flow: column; }
.grid-template-rows-3 { grid-template-rows: repeat(3, 1fr); }

li {
  padding: 2px 4px;
  border: 1px dashed blue;
  display: flex;
  justify-content: center;
  align-items: center;
}
<h3>grid-auto-flow: row</h3>
<ul class="sub-menu grid-auto-flow-row">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
</ul>

<h3>grid-auto-flow: column</h3>
<ul class="sub-menu grid-auto-flow-column">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
</ul>

<h3>grid-auto-flow: column with grid-template-rows explicitly set</h3>
<ul class="sub-menu grid-auto-flow-column grid-template-rows-3">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
</ul>

Upvotes: 2

Views: 259

Answers (1)

focus.style
focus.style

Reputation: 6760

Here is a good answer why it is impossible to do it using display: grid;. So why should we? We have column-count for this task.

More about column-count and it's additional properties.

.sub-menu {
  margin: 0;
  padding: 2px;
  list-style: none;
  border-top: 1px solid;
  
  /* goodbye grid */
  column-count: 3;  
}
<ul class="sub-menu">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
</ul>

<ul class="sub-menu">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
</ul>

<ul class="sub-menu">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
  <li>Item 7</li>
  <li>Item 8</li>
  <li>Item 9</li>
  <li>Item 10</li>
</ul>

Upvotes: 1

Related Questions