问题
I have a dynamic number of elements (all of equal dimensions). I want to position them in a grid, such that they are ordered in columns, with a dynamic number of columns based on the available container width, and with a dynamic number of rows based on the number of elements.
For example, assuming there are 9 elements:
1 4 7
2 5 8
3 6 9
But if the container width expands:
1 3 5 7 9
2 4 6 8
Or shrinks:
1 6
2 7
3 8
4 9
5
This works fine when the items are positioned by row, but not by column. Also, if I explicitly set the number of rows, it works fine, but if I use auto-fill for both rows and columns, it just displays everything in a single row.
Here's a simple example I would expect to be rendered as a 3x3 grid: https://codepen.io/anon/pen/ZxPQNd
#grid {
width: 320px;
border: 1px solid red;
display: grid;
grid-gap: 10px;
grid-auto-flow: column;
grid-template-rows: repeat(auto-fill, 100px);
grid-template-columns: repeat(auto-fill, 100px);
grid-auto-columns: 100px;
grid-auto-rows: 100px;
}
#grid>div {
background: lime;
}
<div id="grid">
<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>
回答1:
Your desired layout is achievable using CSS multi-column layout using column-width
property. Demo:
#grid {
border: 1px solid red;
column-width: 100px;
column-gap: 10px;
}
#grid > div {
break-inside: avoid-column; /* Prevent element from breaking */
page-break-inside: avoid; /* Prevent element from breaking in Firefox */
background: lime;
width: 100px;
height: 100px;
margin-bottom: 10px;
}
<div id="grid">
<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>
回答2:
This works fine when the items are positioned by row, but not by column.
This is because block elements consume the full width of their parent, by default.
But this behavior does not extend to height. Most elements are, by default, the height of their content (i.e., no extra space).
Essentially, your container is set to width: 100%
and height: auto
. For the row behavior in the vertical axis add height: 100vh
.
More info: How to make a div 100% height of the browser window?
#grid {
width: 320px;
border: 1px solid red;
display: grid;
grid-gap: 10px;
grid-auto-flow: column;
grid-template-rows: repeat(auto-fill, 100px);
grid-template-columns: repeat(auto-fill, 100px);
grid-auto-columns: 100px;
grid-auto-rows: 100px;
height: 100vh; /* NEW */
}
#grid > div {
background: lime;
}
<div id="grid">
<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>
In terms of the re-ordering of grid items based on screen size, with grid-auto-flow: row
the items will respond to container width. With grid-auto-flow: column
, the items will respond to container height. To make the column-flowing items respond to width re-sizing will require some trickery.
More info: Make grid items fill columns not rows
来源:https://stackoverflow.com/questions/49764092/create-a-css-grid-that-flows-by-column-with-dynamic-columns-and-rows-based-on-c