Pure CSS Masonry Layout without defined columns

2019-08-05 19:13发布

问题:

I wrote a layout as depicted above. I implemented this with the simple usage of display: inline-block and article elements that have different widths and heights, like so:

width: 50%; /* this is variable*/
height: 160px;  /* this is also variable*/
padding: 10px;
box-sizing: border-box;
display: inline-block;
vertical-align: top;

Now this already works quite okish, but: You see the gap above boxes 4 and 5? Can I write a pure CSS layout that makes these boxes fill up the space directly below 1? I saw some flex-box solutions but they seemed to work with a fixed set of columns, ideally I just want to pass boxes 1-6 in the layout and they adjust properly. Is that possible with modern CSS? I have no browser restrictions and can work with any modern feature!

回答1:

Unfortunately you can't accomplish that with flexbox and I think grid layout would also not do the thing. Pure CSS masonry layout is highly expected, but not yet available.

I see two solutions:

1. Use external package. I would suggest react-grid-layout which uses JS to control position: absolute and transform: translate values of children. It supports resizing and many other features. In your situation it should work just fine.

2. You could also use some tiny JS (pen's not mine):



回答2:

@staypuftman pointed out in a comment to use CSS grids and I accomplished what I wanted to do. This is my code:

On the container:

display: grid;
grid-template-columns: repeat(8, 1fr);
grid-template-rows: repeat(12, 1fr);
grid-gap: 15px;
height: 100vh;

what I do is I use the grid layout, I create 8 columns by writing 1fr 8 times in grid-template-columns and 12 rows with the 12 frs in the grid-template-rows property. Also I set a grid-gap for spacing between each item and a height of 100vh to make my grid span over the whole visible space.

Now within my items I do this:

grid-column-end: span 2;
grid-row-end: span 2;

Where grid-column-end: span X tells the browser to span the item over 2 of my columns (of which I created 8) and the same in regards to rows with grid-row-end.

This is the result: