问题
I would like to achieve a grid effect in CSS with elements that all have the same width in size but not in height. I would like the element underneath to be always at 50px of the bottom one, whatever is next.
I tried with floats, but that bug. So I tried with Flex, but it still does not do what I want.
.container
display: flex
flex-wrap wrap
align-content flex-start
align-items flex-start
What I would like:
What I have:
回答1:
Try the new CSS Grid Layout:
grid-container {
display: grid; /* 1 */
grid-auto-rows: 50px; /* 2 */
grid-gap: 10px; /* 3 */
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); /* 4 */
}
[short] {
grid-row: span 1; /* 5 */
background-color: green;
}
[tall] {
grid-row: span 2;
background-color: crimson;
}
[taller] {
grid-row: span 3;
background-color: blue;
}
[tallest] {
grid-row: span 4;
background-color: gray;
}
<grid-container>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item tall></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item taller></grid-item>
<grid-item short></grid-item>
<grid-item tallest></grid-item>
<grid-item tall></grid-item>
<grid-item short></grid-item>
</grid-container>
jsFiddle demo
How it works:
- Establish a block-level grid container.
- The grid-auto-rows property sets the height of automatically generated rows. In this grid each row is 50px tall.
- The grid-gap property is a shorthand for
grid-column-gap
andgrid-row-gap
. This rule sets a 10px gap between grid items. (It doesn't apply to the area between items and the container.) The grid-template-columns property sets the width of explicitly defined columns.
The repeat notation defines a pattern of repeating columns (or rows).
The auto-fill function tells the grid to line up as many columns (or rows) as possible without overflowing the container. (This can create a similar behavior to flex layout's
flex-wrap: wrap
.)The minmax() function sets a minimum and maximum size range for each column (or row). In the code above, the width of each column will be a minimum of 30% of the container and maximum of whatever free space is available.
The fr unit represents a fraction of the free space in the grid container. It's comparable to flexbox's
flex-grow
property.With grid-row and span we're telling grid items how many rows they should span.
Browser Support for CSS Grid
- Chrome - full support as of March 8, 2017 (version 57)
- Firefox - full support as of March 6, 2017 (version 52)
- Safari - full support as of March 26, 2017 (version 10.1)
- Edge - full support as of October 16, 2017 (version 16)
- IE11 - no support for current spec; supports obsolete version
Here's the complete picture: http://caniuse.com/#search=grid
Cool grid overlay feature in Firefox: In Firefox dev tools, when you inspect the grid container, there is a tiny grid icon in the CSS declaration. On click it displays an outline of your grid on the page.
More details here: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts
回答2:
I would suggest a column layout. It can be easily made responsive to your liking by declaring both column-width
and column-count
. The benefit over Emonadeo's solution (no offense) is that it still remains responsive without any additional markup added. The drawback is, that the elements get sorted into columns first, not rows.
.container {
/* min width of a single column */
column-width: 140px;
/* maximum amount of columns */
column-count: 4;
/* gap between the columns */
column-gap: 16px;
}
.container div {
/* important so a single div never gets distributed between columns */
break-inside: avoid-column;
background-color: #2C2F33;
margin-bottom: 16px;
color:white;
}
<div class="container">
<div style="height: 200px">a</div>
<div style="height: 100px">b</div>
<div style="height: 200px">c</div>
<div style="height: 150px">d</div>
<div style="height: 250px">e</div>
<div style="height: 200px">f</div>
<div style="height: 300px">g</div>
<div style="height: 150px">h</div>
<div style="height: 100px">i</div>
</div>
回答3:
I suggest you put every column in a seperate div
. That way flexbox doesn't force it into a table-like layout.
Even though I used fixed heights in the snippet it should work dynamically without any problem
.container {
display: flex;
}
.col {
flex: 1;
}
.col div {
background-color: #2C2F33;
margin: 16px 8px;
}
<div class="container">
<div class="col">
<div style="height: 200px"></div>
<div style="height: 100px"></div>
<div style="height: 200px"></div>
</div>
<div class="col">
<div style="height: 150px"></div>
<div style="height: 250px"></div>
<div style="height: 200px"></div>
</div>
<div class="col">
<div style="height: 300px"></div>
<div style="height: 150px"></div>
<div style="height: 100px"></div>
</div>
</div>
来源:https://stackoverflow.com/questions/43901955/create-a-masonry-grid-with-flexbox-or-other-css